hashicorp/nomad · critical
failed to start HTTP listener: %v
Error message
failed to start HTTP listener: %v
What it means
Returned by NewHTTPServers (command/agent/http.go:192) when config.Listener fails to open a TCP listener for one of the agent's HTTP addresses. The error is appended to a multierror and that listener skipped; startup fails only if no listener can be created.
Source
Thrown at command/agent/http.go:192
// Enable HTTP2 unless it has been disabled in the configuration.
if !config.HTTPDisableHTTP2 {
protocols.SetHTTP2(true)
// If TLS is not enabled for HTTP, make HTTP2 available over cleartext.
if !config.TLSConfig.EnableHTTP {
protocols.SetUnencryptedHTTP2(true)
}
}
// Start the listener
for _, addr := range config.normalizedAddrs.HTTP {
lnAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
serverInitializationErrors = multierror.Append(serverInitializationErrors, err)
continue
}
ln, err := config.Listener("tcp", lnAddr.IP.String(), lnAddr.Port)
if err != nil {
serverInitializationErrors = multierror.Append(serverInitializationErrors, fmt.Errorf("failed to start HTTP listener: %v", err))
continue
}
// If TLS is enabled, wrap the listener with a TLS listener
if config.TLSConfig.EnableHTTP {
tlsConfig, err := tlsConf.IncomingTLSConfig()
if err != nil {
serverInitializationErrors = multierror.Append(serverInitializationErrors, err)
continue
}
if !config.HTTPDisableHTTP2 {
tlsConfig.NextProtos = []string{ProtoHttp2}
}
ln = tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, tlsConfig)
}
// Create the server
srv := &HTTPServer{View on GitHub (pinned to 482b49bf1a)
Solutions
- Find and stop the conflicting process (lsof -i :4646 / ss -ltnp) or change `ports { http = ... }` to a free port.
- Ensure the configured bind address exists on the host interface.
- Use a non-privileged port or grant the required capability for ports <1024.
- If it occurred during reload, verify addresses in the new config and reload again.
Example fix
// before (HCL)
ports {
http = 4646
}
// after (move off the occupied port)
ports {
http = 14646
} Defensive patterns
Strategy: try-catch
Validate before calling
addr := &net.TCPAddr{IP: net.ParseIP(bindIP), Port: httpPort}
ln, err := net.Listen("tcp", addr.String())
if err != nil {
return fmt.Errorf("http port %d unavailable: %v", httpPort, err)
}
ln.Close() Try / catch
if err := agent.Setup(); err != nil {
if strings.Contains(err.Error(), "failed to start HTTP listener") {
// check lsof -i :4646 for a conflicting process, change ports, retry
}
} Prevention
- Check port availability before starting agents (lsof/ss).
- Use distinct ports per agent or rely on defaults.
- Ensure bind_addr refers to an IP present on the host.
- Clean up crashed agents that hold ports.
When it happens
Trigger: Binding a port already in use by another process or agent, binding to an IP not present on the host, lacking privilege for ports <1024, or bad address syntax in bind_addr/ports during start or HTTP reload.
Common situations: Two agents on one host; a crashed leftover process holding 4646; containers sharing host networking; bind address changed to an IP that no longer exists; SELinux/AppArmor blocking bind.
Related errors
- network namespace already exists but was misconfigured
- network already configured but not found in state
- no CNI network config found
- ErrConnectRequireOneNetwork
- No path to node
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5ab54f45fb6e77d1.
Report an issue: GitHub.