nats-io/nats-server · error
no_auth_user not compatible with Trusted Operator
Error message
no_auth_user not compatible with Trusted Operator
What it means
The no_auth_user option is incompatible with trusted operator mode. When operators (TrustedOperators) are configured, authentication is fully governed by operator/account JWTs and the implicit anonymous-user shortcut of no_auth_user cannot be honored, so the server refuses the combination.
Source
Thrown at server/auth.go:1776
jwt.ConnectionTypeMqtt, jwt.ConnectionTypeMqttWS,
jwt.ConnectionTypeInProcess:
default:
return fmt.Errorf("unknown connection type %q", ct)
}
if ctuc != ct {
delete(m, ct)
m[ctuc] = struct{}{}
}
}
return nil
}
func validateNoAuthUser(o *Options, noAuthUser string) error {
if noAuthUser == _EMPTY_ {
return nil
}
if len(o.TrustedOperators) > 0 {
return fmt.Errorf("no_auth_user not compatible with Trusted Operator")
}
if o.Nkeys == nil && o.Users == nil {
return fmt.Errorf(`no_auth_user: "%s" present, but users/nkeys are not defined`, noAuthUser)
}
for _, u := range o.Users {
if u.Username == noAuthUser {
return nil
}
}
for _, u := range o.Nkeys {
if u.Nkey == noAuthUser {
return nil
}
}
return fmt.Errorf(
`no_auth_user: "%s" not present as user or nkey in authorization block or account configuration`,
noAuthUser)View on GitHub (pinned to 3a66a489d2)
Solutions
- Remove no_auth_user from the configuration when using a trusted operator.
- Define the desired anonymous access as a proper user/nkey in an account with limited permissions instead.
- If operator mode is not intended, remove the operator/resolver configuration instead.
- Reload the server after cleaning the config: `nats-server --signal reload`.
Example fix
// before (config) operator: $OPS resolver: MEMORY no_auth_user: guest // after operator: $OPS resolver: MEMORY # no_auth_user removed; anonymous handled by account-scoped user
Defensive patterns
Strategy: validation
Validate before calling
if opts.NoAuthUser != "" && len(opts.TrustedOperators) > 0 {
return errors.New("no_auth_user cannot be used with trusted operators")
} Try / catch
if err := validateOptions(opts); err != nil {
if strings.Contains(err.Error(), "no_auth_user not compatible") {
log.Fatal("remove no_auth_user from operator-mode config")
}
} Prevention
- Audit config templates when migrating to operator mode
- Search configs for no_auth_user before adding operator blocks
- Encode this incompatibility in config generation tooling
When it happens
Trigger: Starting or validating a server with both `no_auth_user` set in options and one or more TrustedOperators present (validateNoAuthUser). This happens via config file, command line flag, or Options struct assembled in code.
Common situations: Operators migrating an existing open-auth setup to operator-based security who kept no_auth_user in the config; merged config files where an operator block was added while no_auth_user remained.
Related errors
- no_auth_user: "%s" present, but users/nkeys are not defined
- no_auth_user: "%s" not present as user or nkey in authorizat
- credentials have been revoked
- mqtt authentication token not compatible with presence of us
- no operator key found
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/4b5a73e5c93cae06.
Report an issue: GitHub.