The localIp = :: in the log entry is a strong diagnostic signal. That :: (the IPv6 unspecified address) is the local bind address of the listener – meaning the HTTPS listener is bound to [::]:443, which on Linux with dual-stack sockets is normal and means “listen on all interfaces, both IPv4 and IPv6.” The :: in localIp is just showing which end of the socket Stalwart is bound to, not the client’s IP. That part of the log is expected and not a problem.
The key detail in that log line is reason = "end of stream". This means the TCP connection was established (and TLS handshaked, since tls = true is logged) but the client closed the connection without sending any HTTP request data – the stream ended before any application data arrived. This is exactly what AWS NLB TLS health checks do: they complete the TLS handshake to confirm the backend is alive, then immediately close the connection without sending an HTTP request.
Since you’ve confirmed:
- The NLB CIDR is already in Allowed IPs (bypasses auto-ban)
- The NLB IPs are not appearing in Blocked IPs
…then the connection resets after ~1 minute are almost certainly not an auto-ban issue. A few other things to investigate:
1. NLB connection draining / idle timeout interaction
AWS NLBs have a connection idle timeout (default 350 seconds for TCP, 60 seconds for TLS listeners). If TLS termination is happening at the NLB and it re-encrypts to the backend, the NLB may be reusing or draining backend connections in a way that causes Stalwart’s HTTP/2 or keep-alive sessions to break when the NLB rotates or rebalances its backend pool. Check your NLB target group’s deregistration delay and connection draining settings.
2. Are sessions being routed to different cluster nodes?
The admin WebUI uses session tokens. If the NLB is round-robin routing and your cluster nodes don’t share session state for the HTTP admin interface, requests after the initial login may land on a different node that doesn’t recognize the session, causing it to reject the connection. Check whether you have sticky sessions (session affinity) enabled on the NLB target group – for the admin WebUI behind a multi-node cluster, this is typically required.
3. Verify the listener bind address and TLS configuration
In Settings > Network > Listeners, check what bind address your https listener uses. If it’s bound to a specific IPv4 address rather than [::]:443 or 0.0.0.0:443, and the NLB is connecting from an address that maps to a different interface, some connections may be reaching nodes that aren’t properly handling them.
The docs note that binding to [::]:port listens on all interfaces (both IPv4 and IPv6), which is the typical correct setting for a node behind a load balancer.
Docs references:
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.