When I try to start the stalwart server in bootstrap mode (no configuration yet) inside a Jail I’m getting this error:
ERROR Configuration build error (registry.build-error) source = "NetworkListener", id = 20080258862541, reason = "Failed to create socket: Protocol not supported (os error 43)"
I think this might be related to binding the listener to [::]. The openbsd version does seem to contain this fix:
And there was this commit to fix a similar issue on Windows:
I’m wondering if the windows fix would also work for the FreeBSD configuration, but I’m currently unable to build stalwart myself.
Expected Behavior
Stalwart should start in bootstrap mode when no configuration is found
Actual Behavior
It does nit start and displays the described error inside the log file.
Reproduction Steps
Inside a FreeBSD jail:
pkg install stalwart-0.16.18
sysrc stalwart_enable=YES
service stalwart start
Relevant Log Output
2026-09-03T09:33:21Z WARN Server started in bootstrap mode (server.bootstrap-mode) hostname = "stalwart", details = "No configuration file was found. Port 8080 is open for initial setup.", version = "0.16.18"
2026-09-03T09:33:22Z INFO Application resource updated (resource.application-updated) url = "https://github.com/stalwartlabs/webui/releases/latest/download/webui.zip", details = "Stalwart Web Interface"
2026-09-03T09:33:22Z ERROR Configuration build error (registry.build-error) source = "NetworkListener", id = 20080258862541, reason = "Failed to create socket: Protocol not supported (os error 43)"
Stalwart Version
v0.16.x
Installation Method
Binary (FreeBSD)
Database Backend
RocksDB
Blob Storage
Filesystem
Search Engine
Internal
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 understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
Your diagnosis is correct. In the current listener code, when Stalwart tries to build an IPv6 socket for an unspecified bind address ([::]), it only falls back to IPv4 if the OS returns EAFNOSUPPORT:
Err(err) if is_eafnosupport(&err) && addr.is_ipv6() && addr.ip().is_unspecified() => {
// falls back to IPv4
}
and is_eafnosupport checks specifically for EAFNOSUPPORT (errno 47 on BSD-likes), not EPROTONOSUPPORT (errno 43), which is what many FreeBSD jails return for AF_INET6 socket creation when the jail has no IPv6 support enabled. That’s exactly the same class of problem the OpenBSD patch works around, and it isn’t currently handled in the mainline listener code, so the fallback to IPv4 never triggers on FreeBSD jails in that situation.
As a workaround until this is addressed, you can avoid the crash by not letting Stalwart bind to the unspecified IPv6 address at all: explicitly configure your listeners to bind to an IPv4 address (e.g. 0.0.0.0) instead of [::]. This has to be done via the JMAP-based configuration API (or the WebUI/CLI) once you have initial config in place, since bootstrap mode itself binds the setup listener to [::] by default — for the very first bootstrap listener, running the jail with IPv6 enabled (sysrc jail_myjail_ip6=inherit or similar) so socket creation succeeds may be the only way to get past bootstrap.
This is a source-level gap rather than a documented setting, so a maintainer will need to follow up on extending the errno check to cover EPROTONOSUPPORT as well.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.