nats-io/nats-server · error

no operator key found

Error message

no operator key found

What it means

This error comes from the function that determines the operator public key, trusted signing keys, and strict-mode flag used by the JWT resolver setup. When no operator key can be derived — neither from TrustedOperators[0] signing keys nor any other configured source — it returns 'no operator key found', blocking account claim validation/updates.

Source

Thrown at server/accounts.go:4427

	}
}

func getOperatorKeys(s *Server) (string, map[string]struct{}, bool, error) {
	var op string
	var strict bool
	keys := make(map[string]struct{})
	if opts := s.getOpts(); opts != nil && len(opts.TrustedOperators) > 0 {
		op = opts.TrustedOperators[0].Subject
		strict = opts.TrustedOperators[0].StrictSigningKeyUsage
		if !strict {
			keys[opts.TrustedOperators[0].Subject] = struct{}{}
		}
		for _, key := range opts.TrustedOperators[0].SigningKeys {
			keys[key] = struct{}{}
		}
	}
	if len(keys) == 0 {
		return _EMPTY_, nil, false, fmt.Errorf("no operator key found")
	}
	return op, keys, strict, nil
}

func claimValidate(claim *jwt.AccountClaims) error {
	vr := &jwt.ValidationResults{}
	claim.Validate(vr)
	if vr.IsBlocking(false) {
		return fmt.Errorf("validation errors: %v", vr.Errors())
	}
	return nil
}

func removeCb(s *Server, pubKey string) {
	v, ok := s.accounts.Load(pubKey)
	if !ok {
		return
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Configure TrustedOperators in the server config with a claim that includes SigningKeys (or rely on the operator public key being the signing key).
  2. Run `nsc generate config` / update operator JWT so the resolver operator has valid signing keys.
  3. If not using JWT-based accounts, disable the resolver instead of leaving it half-configured.

Example fix

// before
resolver: MEMORY
# no operator configured
// after
resolver: MEMORY
operator: ./operator.jwt # operator claim with signing keys
Defensive patterns

Strategy: validation

Validate before calling

// before starting the server / pushing claims:
if len(opts.TrustedOperators) == 0 || len(opts.TrustedOperators[0].SigningKeys) == 0 {
    return fmt.Errorf("no trusted operator signing keys configured")
}

Prevention

When it happens

Trigger: Starting/using a server with resolver-based account validation where opts.TrustedOperators is empty, or it exists but TrustedOperators[0].SigningKeys is empty, leaving the keys map empty.

Common situations: Operator JWT removed from the server config while resolver is still enabled; an operator claim without signing keys (operator signs everything itself and no explicit keys configured); upgrade/config migration dropping the operator block.

Related errors


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