{"record":{"id":"bcf359d41c23090d","repo":"nats-io/nats-server","slug":"websocket-authentication-username-not-compatible-w","errorCode":null,"errorMessage":"websocket authentication username not compatible with presence of users/nkeys","messagePattern":"websocket authentication username not compatible with presence of users/nkeys","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/websocket.go","lineNumber":1162,"sourceCode":"\t\t}\n\t\tif u.Host == _EMPTY_ {\n\t\t\treturn fmt.Errorf(\"unable to parse allowed origin %q: host is required\", ao)\n\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)","sourceCodeStart":1144,"sourceCodeEnd":1180,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/websocket.go#L1144-L1180","documentation":"The websocket block defines a single Username for authentication while the server options also define a Users (or Nkeys) list; the two auth mechanisms are mutually exclusive. The validator rejects this combination at startup because it would be ambiguous which credentials apply.","triggerScenarios":"Config contains websocket { username: \"u\" } (or authorization block referenced) together with top-level users: [...] or nkeys: [...] in the same options.","commonSituations":"Migrating from simple username auth to multi-user accounts without removing the websocket username; merging config fragments from different environments.","solutions":["Remove websocket.username and define the websocket credentials inside the users list instead","Or remove the users/nkeys entries if single shared username auth is intended","Prefer nkeys/accounts for multi-user setups and drop the legacy username"],"exampleFix":"// before\nwebsocket { username: \"svc\" }\nusers: [{user: \"a\", password: \"p\"}]\n// after\nusers: [{user: \"a\", password: \"p\"}]\n// (websocket credentials come from the users list)","handlingStrategy":"validation","validationCode":"if opts.Websocket.Username != \"\" && (len(opts.Users) > 0 || len(opts.Nkeys) > 0) {\n  return fmt.Errorf(\"websocket.username conflicts with users/nkeys\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one auth model per server: single websocket username OR users/nkeys","Keep auth config centralized in one block to avoid stale leftovers"],"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"}