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

  1. Remove no_auth_user from the configuration when using a trusted operator.
  2. Define the desired anonymous access as a proper user/nkey in an account with limited permissions instead.
  3. If operator mode is not intended, remove the operator/resolver configuration instead.
  4. 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

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


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/4b5a73e5c93cae06. Report an issue: GitHub.