Issue Description
When trying to open https://new-mail.felderer.systems.
Expected Behavior
i should get to the GUI
Actual Behavior
PR_END_OF_FILE_ERROR
Reproduction Steps
- Setup K8S
- use a LoadBalancer without proxy (till everything works but it doesnt sadly)
- get into the GUI via localhost:8080
- create Domain and Cert and also set it in Networks General
- everything works fine under http://new-mail.felderer.systems:443/ (i know its unsecure but at least somethings working)
- getting the error PR_END_OF_FILE_ERROR and cry
Relevant Log Output
saldy i only see logs when in rescue mode ;(
Stalwart Version
v0.16.x
Installation Method
Built from source
Database Backend
PostgreSQL
Blob Storage
S3-compatible
Search Engine
PostgreSQL
Directory Backend
Internal
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I agree to follow the project’s Code of Conduct.
on
PR_END_OF_FILE_ERROR is a TLS handshake failure — the browser connected on port 443 but the server closed the connection without completing a TLS handshake. This is almost always a TLS/certificate configuration issue rather than a Stalwart bug itself. Let me check the relevant docs.
PR_END_OF_FILE_ERROR is a Firefox/browser TLS error that means the server closed the connection without completing a TLS handshake. Based on what you’ve described, the most likely cause is that port 443 is being served as plain HTTP rather than HTTPS — your note that http://new-mail.felderer.systems:443/ works (over HTTP, not HTTPS) confirms this: the listener on port 443 is not set up with TLS enabled.
A few things to check:
-
TLS must be enabled on the HTTPS listener itself. In the Stalwart WebUI under Settings → Network → Listeners, find your port-443 listener and confirm that TLS is toggled on and that the correct certificate is selected for it. Setting a certificate in “General” alone is not sufficient — it must be assigned to (or auto-picked by) the specific listener.
-
Certificate availability. Make sure the certificate you created for new-mail.felderer.systems is fully provisioned and shows as valid in Settings → Network → TLS Certificates. If it was issued via ACME, verify the ACME challenge succeeded.
-
Kubernetes / LoadBalancer TLS termination. If your LoadBalancer or Ingress controller is doing TLS termination before traffic reaches Stalwart, then Stalwart should be listening on plain HTTP on the backend port, and TLS should not be enabled on that listener — but then the LoadBalancer must be configured to terminate TLS correctly. Conversely, if you want Stalwart to handle TLS end-to-end (passthrough), TLS termination must be disabled on the LoadBalancer/Ingress.
-
Logs in rescue mode. Since you can access logs in rescue mode, look for any TLS handshake errors or certificate-loading errors at startup — these will tell you quickly if the cert failed to load.
The core fix is almost always: enable TLS on the port-443 listener in Stalwart’s network settings and ensure the certificate is correctly assigned to that listener.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong. If you found it useful, mention @helpbot in any reply to ask follow-up questions and the bot will respond again.
@helpbot And WHERE WHEREERERER should this setting be? I cant find it anywhere the only setting i found where i can select a cert is in Networks General … and i did assign it … i dont have tls enabled on the LoadBalancer i am using HCloud
service:
type: LoadBalancer
externalTrafficPolicy: Local
annotations:
load-balancer.hetzner.cloud/name: "stalwart-mail-lb"
load-balancer.hetzner.cloud/location: "fsn1"
load-balancer.hetzner.cloud/type: "lb21"
load-balancer.hetzner.cloud/uses-proxyprotocol: "false"
ports:
smtp: 25
smtps: 465
submission: 587
imap: 143
imaps: 993
pop3: 110
pop3s: 995
sieve: 4190
http: 80
https: 443
mgmt: 8080
i saw you’ve got non-default ports listed in your LoadBalancer config (although i have never used k8s so apologies if i am being stupid), those being 587, 143, 80 so assume you have customised your listener config?
my first guess would be that when editing them (or maybe due to the insanely buggy migration script) the https listener on 443 has had “TLS” or “Implicit TLS” disabled - just check both are on :3
you can do that here:
/admin/Settings/x:NetworkListener
if that doesn’t help, please could you share your full network listener config
console logs can be enabled at /admin/Settings/x:Tracer, just add a new tracer and enable colours if you’re feeling fancy!
I am running Stalwart on Kubernetes for more than an year and It is working just fine.
Since you access the admin console on port 443 via HTTP, instead of HTTPS, that makes me believe that the listener on port 443 is not configured with implicit TLS.
Open the admin console and go to context path admin/Settings/x:NetworkListener.
Click on the listener bound on port 443, scroll down to the “TLS options” section and make sure that “Enable TLS” and “Implicit TLS” are enabled.