{"record":{"id":"a3037885247b739a","repo":"nats-io/nats-server","slug":"default-sentinel-requires-operators-and-accounts","errorCode":null,"errorMessage":"default sentinel requires operators and accounts","messagePattern":"default sentinel requires operators and accounts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jwt.go","lineNumber":74,"sourceCode":"\t}\n\treturn theJWT, opc, nil\n}\n\n// Just wipe slice with 'x', for clearing contents of nkey seed file.\nfunc wipeSlice(buf []byte) {\n\tfor i := range buf {\n\t\tbuf[i] = 'x'\n\t}\n}\n\n// validateTrustedOperators will check that we do not have conflicts with\n// assigned trusted keys and trusted operators. If operators are defined we\n// will expand the trusted keys in options.\nfunc validateTrustedOperators(o *Options) error {\n\tif len(o.TrustedOperators) == 0 {\n\t\t// if we have no operator, default sentinel shouldn't be set\n\t\tif o.DefaultSentinel != _EMPTY_ {\n\t\t\treturn fmt.Errorf(\"default sentinel requires operators and accounts\")\n\t\t}\n\t\treturn nil\n\t}\n\tif o.DefaultSentinel != _EMPTY_ {\n\t\tjuc, err := jwt.DecodeUserClaims(o.DefaultSentinel)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"default sentinel JWT not valid\")\n\t\t}\n\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\")","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jwt.go#L56-L92","documentation":"validateTrustedOperators in server/jwt.go enforces that the DefaultSentinel option (a user JWT used as a default account placeholder) can only be configured when trusted operators are also configured. If TrustedOperators is empty but DefaultSentinel is set, startup validation fails with 'default sentinel requires operators and accounts'.","triggerScenarios":"Starting nats-server with `default_sentinel` set in config (or Options.DefaultSentinel set programmatically) without `operator`/`resolver` based trusted operators configured, i.e. in a non-operator mode server.","commonSituations":"Copying a config file from an operator-mode deployment into a plain single-account/dev server; enabling default sentinel for auth without adopting the operator/JWT setup.","solutions":["Remove the default_sentinel setting from nats.conf if operator mode is not used.","Configure operators instead: set `operator` JWT and an account resolver (and move accounts into JWTs).","Restart and confirm `nats server info` shows the trusted keys/operators loaded."],"exampleFix":"// before (nats.conf)\ndefault_sentinel: \"eyJ...\"\n// after: either remove the line, or add operator setup\noperator: \"eyJ...\"\nresolver: MEMORY\nresolver_preload: { ACC: \"eyJ...\" }\ndefault_sentinel: \"eyJ...\"","handlingStrategy":"validation","validationCode":"# before starting the server\nif grep -q '^default_sentinel:' nats.conf && ! grep -q '^operator:' nats.conf; then\n  echo \"default_sentinel requires operator mode\"; exit 1\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only set default_sentinel in operator-mode deployments.","Validate config with `nats-server -t` (config test) before restart.","Template configs per deployment mode so sentinel is not copied into non-operator setups.","Document default_sentinel's dependency on TrustedOperators in runbooks."],"tags":["config","authentication","jwt","operator-mode"],"backgroundTag":"default-sentinel-misconfigured","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}