nats-io/nats-server · error
websocket requires TLS configuration
Error message
websocket requires TLS configuration
What it means
The websocket block validation (websocket.go, options validation) enforces that a TLS configuration is provided unless NoTLS is explicitly set. Because plain websocket (ws://) without explicit opt-out is considered unsafe/misconfigured, the server refuses to start. FIPS builds with an older Go are rejected beforehand with a separate message.
Source
Thrown at server/websocket.go:1134
if _, err := io.ReadFull(crand.Reader, p); err != nil {
return _EMPTY_, err
}
return base64.StdEncoding.EncodeToString(p), nil
}
// Validate the websocket related options.
func validateWebsocketOptions(o *Options) error {
wo := &o.Websocket
// If no port is defined, we don't care about other options
if wo.Port == 0 {
return nil
}
if !wsAllowedFIPS() {
return fmt.Errorf("websocket: cannot be used in FIPS-140 mode when built with this Go version, use Go 1.26 or later")
}
// Enforce TLS... unless NoTLS is set to true.
if wo.TLSConfig == nil && !wo.NoTLS {
return errors.New("websocket requires TLS configuration")
}
// Make sure that allowed origins, if specified, can be parsed.
for _, ao := range wo.AllowedOrigins {
u, err := url.ParseRequestURI(ao)
if err != nil {
return fmt.Errorf("unable to parse allowed origin: %v", err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("unable to parse allowed origin %q: allowed origins must be absolute URLs with http or https scheme", ao)
}
if u.Host == _EMPTY_ {
return fmt.Errorf("unable to parse allowed origin %q: host is required", ao)
}
if _, _, err := wsGetHostAndPort(u.Scheme == "https", u.Host); err != nil {
return fmt.Errorf("unable to parse allowed origin: %v", err)
}
}
// If there is a NoAuthUser, we need to have Users defined andView on GitHub (pinned to 3a66a489d2)
Solutions
- Add a tls block (cert_file/key_file) under websocket {} to enable TLS
- If you intentionally want plain ws://, set `no_tls: true` in the websocket block
- When building Options in code, assign Websocket.TLSConfig or set Websocket.NoTLS = true
- If on FIPS mode with Go < 1.26, upgrade the build toolchain per the adjacent FIPS error
Example fix
// before (server.conf)
websocket {
port: 8080
}
// after
websocket {
port: 8080
no_tls: true
} Defensive patterns
Strategy: validation
Validate before calling
// before starting the server programmatically
func validateWebsocketOpts(wo *server.WebsocketOpts) error {
if wo == nil || (wo.TLSConfig == nil && !wo.NoTLS) {
return errors.New("websocket: set TLSConfig or NoTLS=true")
}
return nil
} Prevention
- Always pair a websocket block with either tls {} or no_tls: true
- Validate configs with nats-server -t in CI
- Document that TLS at an external proxy still requires no_tls: true locally
- Review FIPS/Go version requirements before enabling websockets in FIPS builds
When it happens
Trigger: Config contains a websocket {} block but no tls {} sub-block (TLSConfig is nil) and no `no_tls: true`; programmatic Options set Websocket without TLSConfig and leave NoTLS false.
Common situations: Dev setups intending plain ws:// but forgetting no_tls: true; TLS configured at an external proxy but not in NATS while no_tls wasn't set; copying a production config and removing the TLS block.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- unable to register client OCSP verification
- mqtt requires JetStream to be enabled if running in standalo
- unable to plug TLS verify connection, config is nil
- OCSP peer verification for client connections requires TLS v
- no hostport specified
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/484df517137ef333.
Report an issue: GitHub.