{"record":{"id":"951ae30dbedb9760","repo":"nats-io/nats-server","slug":"can-not-have-a-single-user-pass-and-a-users-array","errorCode":null,"errorMessage":"can not have a single user/pass and a users array","messagePattern":"can not have a single user/pass and a users array","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/leafnode.go","lineNumber":376,"sourceCode":"\tif ok, err := versionAtLeastCheckError(mv, 2, 8, 0); !ok || err != nil {\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid leafnode's minimum version: %v\", err)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"the minimum version should be at least 2.8.0\")\n\t\t}\n\t}\n\treturn nil\n}\n\n// Used to validate user names in LeafNode configuration.\n// - rejects mix of single and multiple users.\n// - rejects duplicate user names.\nfunc validateLeafNodeAuthOptions(o *Options) error {\n\tif len(o.LeafNode.Users) == 0 {\n\t\treturn nil\n\t}\n\tif o.LeafNode.Username != _EMPTY_ {\n\t\treturn fmt.Errorf(\"can not have a single user/pass and a users array\")\n\t}\n\tif o.LeafNode.Nkey != _EMPTY_ {\n\t\treturn fmt.Errorf(\"can not have a single nkey and a users array\")\n\t}\n\tusers := map[string]struct{}{}\n\tfor _, u := range o.LeafNode.Users {\n\t\tif _, exists := users[u.Username]; exists {\n\t\t\treturn fmt.Errorf(\"duplicate user %q detected in leafnode authorization\", u.Username)\n\t\t}\n\t\tusers[u.Username] = struct{}{}\n\t}\n\treturn nil\n}\n\nfunc validateLeafNodeProxyOptions(remote *RemoteLeafOpts) ([]string, error) {\n\tvar warnings []string\n\n\tif remote.Proxy.URL == _EMPTY_ {","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/leafnode.go#L358-L394","documentation":"validateLeafNodeAuthOptions enforces that leaf node authorization uses either the single Username/Password form or the Users array, not both. If Users is non-empty and LeafNode.Username is also set, configuration is ambiguous, so this error is thrown during validation (via validateLeafNode or parseLeafNodes).","triggerScenarios":"Options where o.LeafNode.Users has >= 1 entry and o.LeafNode.Username != \"\" — e.g. config with both `user:`/`pass:` and a `users:` array under the leafnode block; triggered by NewServer/Validate or leafnode config parsing.","commonSituations":"Merging an old single-user leafnode auth block with a newer users array during config refactors; automation tools appending a users array while leaving legacy user/pass keys in place.","solutions":["Remove the single `user`/`pass` keys and keep only the users array","Or remove the users array and keep the single user/pass","Re-run `nats-server -t` (config test) to confirm validation passes"],"exampleFix":"// before\nleafnodes {\n  user: \"leaf\"\n  pass: \"secret\"\n  users = [ { user: \"a\", pass: \"p1\" }, { user: \"b\", pass: \"p2\" } ]\n}\n// after\nleafnodes {\n  users = [ { user: \"a\", pass: \"p1\" }, { user: \"b\", pass: \"p2\" } ]\n}","handlingStrategy":"validation","validationCode":"if len(cfg.LeafNodes.Users) > 0 && cfg.LeafNodes.Username != \"\" {\n  return errors.New(\"use either single user/pass or users array, not both\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Migrate fully to the users array form","Lint configs for legacy single-user leafnode keys","Keep auth blocks in one template, not merged ad hoc"],"tags":["leafnode","auth","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"}