nats-io/nats-server · error

websocket authentication token not compatible with presence

Error message

websocket authentication token not compatible with presence of users/nkeys

What it means

The websocket block defines an authentication Token while the server options also define a Users (or Nkeys) list; these mechanisms are mutually exclusive and the validator rejects the combination at startup.

Source

Thrown at server/websocket.go:1165

		}
		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 and
	// 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",

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Remove websocket.token and put the token credential in the users list (user with password/token)
  2. Or drop users/nkeys if simple shared-token auth is intended
  3. Move to nkeys/accounts for token-based multi-tenant auth

Example fix

// before
websocket { token: "s3cret" }
nkeys: ["UBO..."]
// after
nkeys: ["UBO..."]
// (token removed; nkeys govern auth)
Defensive patterns

Strategy: validation

Validate before calling

if opts.Websocket.Token != "" && (len(opts.Users) > 0 || len(opts.Nkeys) > 0) {
  return fmt.Errorf("websocket.token conflicts with users/nkeys")
}

Prevention

When it happens

Trigger: Config contains websocket { token: "..." } alongside users: [...] or nkeys: [...] in the same options.

Common situations: Mixing legacy single-token auth with the multi-user authorization list, often after refactoring auth or copying blocks between server configs.

Understand the failure class

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/c39e91b2555c37b4. Report an issue: GitHub.