{"record":{"id":"c39e91b2555c37b4","repo":"nats-io/nats-server","slug":"websocket-authentication-token-not-compatible-with","errorCode":null,"errorMessage":"websocket authentication token not compatible with presence of users/nkeys","messagePattern":"websocket authentication token not compatible with presence of users/nkeys","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/websocket.go","lineNumber":1165,"sourceCode":"\t\t}\n\t\tif _, _, err := wsGetHostAndPort(u.Scheme == \"https\", u.Host); err != nil {\n\t\t\treturn fmt.Errorf(\"unable to parse allowed origin: %v\", err)\n\t\t}\n\t}\n\t// If there is a NoAuthUser, we need to have Users defined and\n\t// the user to be present.\n\tif wo.NoAuthUser != _EMPTY_ {\n\t\tif err := validateNoAuthUser(o, wo.NoAuthUser); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Token/Username not possible if there are users/nkeys\n\tif len(o.Users) > 0 || len(o.Nkeys) > 0 {\n\t\tif wo.Username != _EMPTY_ {\n\t\t\treturn fmt.Errorf(\"websocket authentication username not compatible with presence of users/nkeys\")\n\t\t}\n\t\tif wo.Token != _EMPTY_ {\n\t\t\treturn fmt.Errorf(\"websocket authentication token not compatible with presence of users/nkeys\")\n\t\t}\n\t}\n\t// Using JWT requires Trusted Keys\n\tif wo.JWTCookie != _EMPTY_ {\n\t\tif len(o.TrustedOperators) == 0 && len(o.TrustedKeys) == 0 {\n\t\t\treturn fmt.Errorf(\"trusted operators or trusted keys configuration is required for JWT authentication via cookie %q\", wo.JWTCookie)\n\t\t}\n\t}\n\tif err := validatePinnedCerts(wo.TLSPinnedCerts); err != nil {\n\t\treturn fmt.Errorf(\"websocket: %v\", err)\n\t}\n\n\t// Check for invalid headers here.\n\tfor key := range wo.Headers {\n\t\tk := strings.ToLower(key)\n\t\tswitch k {\n\t\tcase \"host\",\n\t\t\t\"content-length\",","sourceCodeStart":1147,"sourceCodeEnd":1183,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/websocket.go#L1147-L1183","documentation":"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.","triggerScenarios":"Config contains websocket { token: \"...\" } alongside users: [...] or nkeys: [...] in the same options.","commonSituations":"Mixing legacy single-token auth with the multi-user authorization list, often after refactoring auth or copying blocks between server configs.","solutions":["Remove websocket.token and put the token credential in the users list (user with password/token)","Or drop users/nkeys if simple shared-token auth is intended","Move to nkeys/accounts for token-based multi-tenant auth"],"exampleFix":"// before\nwebsocket { token: \"s3cret\" }\nnkeys: [\"UBO...\"]\n// after\nnkeys: [\"UBO...\"]\n// (token removed; nkeys govern auth)","handlingStrategy":"validation","validationCode":"if opts.Websocket.Token != \"\" && (len(opts.Users) > 0 || len(opts.Nkeys) > 0) {\n  return fmt.Errorf(\"websocket.token conflicts with users/nkeys\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remove legacy websocket token when migrating to users/nkeys","Test config with a dry-run parse in CI before rollout"],"tags":["websocket","authentication","config-validation"],"backgroundTag":"conflicting-auth-config","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}