Summary
After upgrading to UmbrelOS 2.0, the Stalwart Mail Server WebUI is no longer accessible through its published HTTPS port.
The Stalwart container itself is healthy and HTTPS works correctly from inside the container and from another container on the same Docker network. The failure appears to be specifically between the Umbrel host and the Docker-published HTTPS port.
Environment
-
UmbrelOS: 2.0
-
Docker Server: 28.5.0
-
App: Stalwart Mail Server
-
Container: stalwart_server_1
-
Docker network: umbrel_main_network
-
Docker subnet: 10.21.0.0/16
-
Stalwart container IP: 10.21.0.2
Docker port mapping
Stalwart exposes:
10025 -> 25
10110 -> 110
10143 -> 143
10443 -> 443
10465 -> 465
10587 -> 587
10993 -> 993
10995 -> 995
14190 -> 4190
The container is reported as:
Up 2 days (healthy)
What works
From inside the Stalwart container:
https://127.0.0.1:443/ -> HTTP 302 /account
https://10.21.0.2:443/ -> HTTP 302 /account
A separate temporary container on the same Docker network can also access Stalwart:
curl https://10.21.0.2:443/
-> TLS 1.3 succeeds
-> HTTP/1.1 302 Found
-> location: /account
The Stalwart certificate is presented correctly:
CN=mail.zappy.email
Let's Encrypt
What fails
From the Umbrel host:
curl https://127.0.0.1:10443/
-> TLS unexpected EOF
curl https://10.21.0.2:443/
-> TLS unexpected EOF
Using the correct hostname/SNI does not change the result:
curl --resolve mail.zappy.email:10443:127.0.0.1 \
https://mail.zappy.email:10443/
-> TLS unexpected EOF
For comparison, the other published Stalwart ports are reachable from the host:
10025 -> OPEN
10587 -> OPEN
10993 -> OPEN
10465 -> OPEN
So this does not appear to be a general Docker networking failure.
Docker/nftables observations
Docker has the expected DNAT rule:
tcp dport 10443 dnat to 10.21.0.2:443
The corresponding Docker filter rule also exists:
-d 10.21.0.2/32
-o br-015376facc3d
-p tcp
--dport 443
-j ACCEPT
The Docker bridge is:
br-015376facc3d
10.21.0.1/16
The Stalwart container is:
10.21.0.2
Additional environment information
A privileged host-network Docker container is running:
portainer_docker_1
network=host
privileged=true
There is also:
wireguard-tunnel_server_1
network=host
privileged=false
I am not claiming either container is responsible; this is included for debugging context.
Expected behavior
The published port:
127.0.0.1:10443 -> 10.21.0.2:443
should allow the Umbrel host/reverse proxy to establish a normal TLS connection to Stalwart.
Actual behavior
The TCP connection reaches the published port, but TLS is terminated with:
SSL error: unexpected eof while reading
while the exact same Stalwart HTTPS listener works normally from inside Docker.
Important observation
This started after the UmbrelOS 2.0 upgrade. No Stalwart configuration changes were intentionally made to cause this behavior.
Could this be related to the UmbrelOS 2.0 Docker/nftables/iptables-nft networking changes or regression in handling host-to-published-container HTTPS traffic?
I can provide the complete nft list ruleset, Docker network inspection, container inspection, and curl diagnostics if needed.