nats-io/nats-server · error
conflicting options for 'TrustedKeys' and 'TrustedOperators'
Error message
conflicting options for 'TrustedKeys' and 'TrustedOperators'
What it means
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.
Source
Thrown at server/jwt.go:101
if !juc.BearerToken && juc.IssuerAccount != "" && juc.HasEmptyPermissions() {
// we cannot resolve the account yet - but this looks like a scoped user
// it will be rejected at runtime if not valid
} else if !juc.BearerToken {
return fmt.Errorf("default sentinel must be a bearer token")
}
}
if o.AccountResolver == nil {
return fmt.Errorf("operators require an account resolver to be configured")
}
if len(o.Accounts) > 0 {
return fmt.Errorf("operators do not allow Accounts to be configured directly")
}
if len(o.Users) > 0 || len(o.Nkeys) > 0 {
return fmt.Errorf("operators do not allow users to be configured directly")
}
if len(o.TrustedOperators) > 0 && len(o.TrustedKeys) > 0 {
return fmt.Errorf("conflicting options for 'TrustedKeys' and 'TrustedOperators'")
}
if o.SystemAccount != _EMPTY_ {
foundSys := false
foundNonEmpty := false
for _, op := range o.TrustedOperators {
if op.SystemAccount != _EMPTY_ {
foundNonEmpty = true
}
if op.SystemAccount == o.SystemAccount {
foundSys = true
break
}
}
if foundNonEmpty && !foundSys {
return fmt.Errorf("system_account in config and operator JWT must be identical")
}
} else if o.TrustedOperators[0].SystemAccount == _EMPTY_ {
// In case the system account is neither defined in config nor in the first operator.View on GitHub (pinned to 3a66a489d2)
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
Example fix
// before trusted: [OAF...] operator: eyJ... // after operator: eyJ...
Defensive patterns
Strategy: validation
Validate before calling
// Go: detect dual trust anchors
if len(o.TrustedOperators) > 0 && len(o.TrustedKeys) > 0 {
return fmt.Errorf("choose either trusted keys or operators")
} Prevention
- 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
When it happens
Trigger: Config sets both `operator: [...]` and `trusted: [keys...]`; validateOptions fails at startup.
Common situations: Upgrading from trusted-keys configs to operator JWTs and leaving the `trusted:` line behind; adding an operator JWT to an existing trusted-keys server.
Related errors
- operators require an account resolver to be configured
- operators do not allow Accounts to be configured directly
- operators do not allow users to be configured directly
- system_account in config and operator JWT must be identical
- operator %s expects version %s got error instead: %s
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/20266835ef60b746.
Report an issue: GitHub.