nats-io/nats-server · error
trusted operators or trusted keys configuration is required
Error message
trusted operators or trusted keys configuration is required for JWT authentication via cookie %q
What it means
JWT-based websocket authentication (websocket.jwt_cookie) requires the server to trust decentralized auth: either trusted operator claims (TrustedOperators) or explicit trusted public NKeys (TrustedKeys). Without one of these, JWTs in the cookie cannot be verified, so the validator refuses to start.
Source
Thrown at server/websocket.go:1171
// the user to be present.
if wo.NoAuthUser != _EMPTY_ {
if err := validateNoAuthUser(o, wo.NoAuthUser); err != nil {
return err
}
}
// Token/Username not possible if there are users/nkeys
if len(o.Users) > 0 || len(o.Nkeys) > 0 {
if wo.Username != _EMPTY_ {
return fmt.Errorf("websocket authentication username not compatible with presence of users/nkeys")
}
if wo.Token != _EMPTY_ {
return fmt.Errorf("websocket authentication token not compatible with presence of users/nkeys")
}
}
// Using JWT requires Trusted Keys
if wo.JWTCookie != _EMPTY_ {
if len(o.TrustedOperators) == 0 && len(o.TrustedKeys) == 0 {
return fmt.Errorf("trusted operators or trusted keys configuration is required for JWT authentication via cookie %q", wo.JWTCookie)
}
}
if err := validatePinnedCerts(wo.TLSPinnedCerts); err != nil {
return fmt.Errorf("websocket: %v", err)
}
// Check for invalid headers here.
for key := range wo.Headers {
k := strings.ToLower(key)
switch k {
case "host",
"content-length",
"connection",
"upgrade",
"nats-no-masking":
return fmt.Errorf("websocket: invalid header %q not allowed", key)
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Add the operator JWT via the operator or resolver config so TrustedOperators is populated
- Or add trusted_keys with the operator/signing account public keys to the config
- Or remove jwt_cookie if JWT auth is not intended
Example fix
// before
websocket { jwt_cookie: "nats_jwt" }
// after
operator: ./operator.jwt
resolver: MEMORY
websocket { jwt_cookie: "nats_jwt" } Defensive patterns
Strategy: validation
Validate before calling
if opts.Websocket.JWTCookie != "" && len(opts.TrustedOperators) == 0 && len(opts.TrustedKeys) == 0 {
return fmt.Errorf("jwt_cookie requires trusted operators or trusted keys")
} Prevention
- Pair every jwt_cookie setting with operator JWT or trusted_keys in the same config review
- Keep operator/trusted keys in version-controlled config templates
When it happens
Trigger: Setting websocket { jwt_cookie: "..." } in a config that has no operator JWT file and no trusted_keys entries.
Common situations: Enabling decentralized JWT auth on a standalone server that was set up without operators; forgetting to sync trusted keys after operator rotation.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- operators require an account resolver to be configured
- operators do not allow Accounts to be configured directly
- operators do not allow users to be configured directly
- conflicting options for 'TrustedKeys' and 'TrustedOperators'
- system_account in config and operator JWT must be identical
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/ab22411811fbc05e.
Report an issue: GitHub.