{"record":{"id":"20266835ef60b746","repo":"nats-io/nats-server","slug":"conflicting-options-for-trustedkeys-and-trusted","errorCode":null,"errorMessage":"conflicting options for 'TrustedKeys' and 'TrustedOperators'","messagePattern":"conflicting options for 'TrustedKeys' and 'TrustedOperators'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jwt.go","lineNumber":101,"sourceCode":"\n\t\tif !juc.BearerToken && juc.IssuerAccount != \"\" && juc.HasEmptyPermissions() {\n\t\t\t// we cannot resolve the account yet - but this looks like a scoped user\n\t\t\t// it will be rejected at runtime if not valid\n\t\t} else if !juc.BearerToken {\n\t\t\treturn fmt.Errorf(\"default sentinel must be a bearer token\")\n\t\t}\n\t}\n\tif o.AccountResolver == nil {\n\t\treturn fmt.Errorf(\"operators require an account resolver to be configured\")\n\t}\n\tif len(o.Accounts) > 0 {\n\t\treturn fmt.Errorf(\"operators do not allow Accounts to be configured directly\")\n\t}\n\tif len(o.Users) > 0 || len(o.Nkeys) > 0 {\n\t\treturn fmt.Errorf(\"operators do not allow users to be configured directly\")\n\t}\n\tif len(o.TrustedOperators) > 0 && len(o.TrustedKeys) > 0 {\n\t\treturn fmt.Errorf(\"conflicting options for 'TrustedKeys' and 'TrustedOperators'\")\n\t}\n\tif o.SystemAccount != _EMPTY_ {\n\t\tfoundSys := false\n\t\tfoundNonEmpty := false\n\t\tfor _, op := range o.TrustedOperators {\n\t\t\tif op.SystemAccount != _EMPTY_ {\n\t\t\t\tfoundNonEmpty = true\n\t\t\t}\n\t\t\tif op.SystemAccount == o.SystemAccount {\n\t\t\t\tfoundSys = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif foundNonEmpty && !foundSys {\n\t\t\treturn fmt.Errorf(\"system_account in config and operator JWT must be identical\")\n\t\t}\n\t} else if o.TrustedOperators[0].SystemAccount == _EMPTY_ {\n\t\t// In case the system account is neither defined in config nor in the first operator.","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jwt.go#L83-L119","documentation":"A config may specify trust either via the legacy `trusted` keys list (TrustedKeys) or via `operator` entries (TrustedOperators), not both. This error is thrown when both are present, since the effective trust anchors would be ambiguous.","triggerScenarios":"Config sets both `operator: [...]` and `trusted: [keys...]`; validateOptions fails at startup.","commonSituations":"Upgrading from trusted-keys configs to operator JWTs and leaving the `trusted:` line behind; adding an operator JWT to an existing trusted-keys server.","solutions":["Remove the `trusted:` keys line and rely solely on operator JWTs (preferred)","Or remove the `operator:` line if you still want raw trusted-key mode"],"exampleFix":"// before\ntrusted: [OAF...]\noperator: eyJ...\n// after\noperator: eyJ...","handlingStrategy":"validation","validationCode":"// Go: detect dual trust anchors\nif len(o.TrustedOperators) > 0 && len(o.TrustedKeys) > 0 {\n    return fmt.Errorf(\"choose either trusted keys or operators\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remove the legacy `trusted:` line when adding operator JWTs","Only migrate configs one trust model at a time","Validate configs with `nats-server -t` before deploy"],"tags":["nats","jwt","config-validation","operator-mode"],"backgroundTag":"conflicting-config-options","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}