nats-io/nats-server · error
operator %s expected minor version %d > server minor version
Error message
operator %s expected minor version %d > server minor version %d
What it means
Similar to the major check: the operator asserts a minimum minor version. If the operator's minor version exceeds the running server's (with major equal), the server refuses to start since required features may be missing.
Source
Thrown at server/jwt.go:137
// In case the system account is neither defined in config nor in the first operator.
// If it would be needed due to the nats account resolver, raise an error.
switch o.AccountResolver.(type) {
case *DirAccResolver, *CacheDirAccResolver:
return fmt.Errorf("using nats based account resolver - the system account needs to be specified in configuration or the operator jwt")
}
}
srvMajor, srvMinor, srvUpdate, _ := versionComponents(VERSION)
for _, opc := range o.TrustedOperators {
if major, minor, update, err := jwt.ParseServerVersion(opc.AssertServerVersion); err != nil {
return fmt.Errorf("operator %s expects version %s got error instead: %s",
opc.Subject, opc.AssertServerVersion, err)
} else if major > srvMajor {
return fmt.Errorf("operator %s expected major version %d > server major version %d",
opc.Subject, major, srvMajor)
} else if srvMajor > major {
} else if minor > srvMinor {
return fmt.Errorf("operator %s expected minor version %d > server minor version %d",
opc.Subject, minor, srvMinor)
} else if srvMinor > minor {
} else if update > srvUpdate {
return fmt.Errorf("operator %s expected update version %d > server update version %d",
opc.Subject, update, srvUpdate)
}
}
// If we have operators, fill in the trusted keys.
// FIXME(dlc) - We had TrustedKeys before TrustedOperators. The jwt.OperatorClaims
// has a DidSign(). Use that longer term. For now we can expand in place.
for _, opc := range o.TrustedOperators {
if o.TrustedKeys == nil {
o.TrustedKeys = make([]string, 0, 4)
}
if !opc.StrictSigningKeyUsage {
o.TrustedKeys = append(o.TrustedKeys, opc.Subject)
}
o.TrustedKeys = append(o.TrustedKeys, opc.SigningKeys...)View on GitHub (pinned to 3a66a489d2)
Solutions
- Upgrade nats-server to at least the asserted minor version
- Or lower the operator's assert with `nsc edit operator ...` / reissue the JWT
Example fix
// before server: 2.10.11, operator asserts 2.11.0 // after upgrade server to >= 2.11.0 # or reissue operator asserting 2.10.0
Defensive patterns
Strategy: validation
Validate before calling
// Go: compare asserted minor against running server before startup
_, srvMinor, _, _ := versionComponents(VERSION)
if _, minor, _, err := jwt.ParseServerVersion(opc.AssertServerVersion); err == nil && minor > srvMinor {
return fmt.Errorf("server too old for operator (minor %d > %d)", minor, srvMinor)
} Prevention
- Track operator assert versions in a fleet inventory
- Roll server upgrades out before pushing new operator JWTs
- Use staging to test version-asserting operators against target server versions
When it happens
Trigger: Operator JWT asserts e.g. 2.11.0 while running nats-server 2.10.x; validateOptions minor comparison fails.
Common situations: Operator updated with newer nsc (asserting latest features) but the server cluster not yet upgraded; mixed-version fleets where one config is pushed everywhere.
Related errors
- operator %s expected major version %d > server major version
- operator %s expected update version %d > server update versi
- 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
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/d770ace370f39b8a.
Report an issue: GitHub.