nats-io/nats-server · error

default sentinel requires operators and accounts

Error message

default sentinel requires operators and accounts

What it means

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'.

Source

Thrown at server/jwt.go:74

	}
	return theJWT, opc, nil
}

// Just wipe slice with 'x', for clearing contents of nkey seed file.
func wipeSlice(buf []byte) {
	for i := range buf {
		buf[i] = 'x'
	}
}

// validateTrustedOperators will check that we do not have conflicts with
// assigned trusted keys and trusted operators. If operators are defined we
// will expand the trusted keys in options.
func validateTrustedOperators(o *Options) error {
	if len(o.TrustedOperators) == 0 {
		// if we have no operator, default sentinel shouldn't be set
		if o.DefaultSentinel != _EMPTY_ {
			return fmt.Errorf("default sentinel requires operators and accounts")
		}
		return nil
	}
	if o.DefaultSentinel != _EMPTY_ {
		juc, err := jwt.DecodeUserClaims(o.DefaultSentinel)
		if err != nil {
			return fmt.Errorf("default sentinel JWT not valid")
		}

		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")

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Remove the default_sentinel setting from nats.conf if operator mode is not used.
  2. Configure operators instead: set `operator` JWT and an account resolver (and move accounts into JWTs).
  3. Restart and confirm `nats server info` shows the trusted keys/operators loaded.

Example fix

// before (nats.conf)
default_sentinel: "eyJ..."
// after: either remove the line, or add operator setup
operator: "eyJ..."
resolver: MEMORY
resolver_preload: { ACC: "eyJ..." }
default_sentinel: "eyJ..."
Defensive patterns

Strategy: validation

Validate before calling

# before starting the server
if grep -q '^default_sentinel:' nats.conf && ! grep -q '^operator:' nats.conf; then
  echo "default_sentinel requires operator mode"; exit 1
fi

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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