{"record":{"id":"37bfb23efdd2ba11","repo":"nats-io/nats-server","slug":"operator-s-expected-major-version-d-server-maj","errorCode":null,"errorMessage":"operator %s expected major version %d > server major version %d","messagePattern":"operator (.+?) expected major version (.+?) > server major version (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jwt.go","lineNumber":133,"sourceCode":"\t\tif foundNonEmpty && !foundSys {\n\t\t\treturn fmt.Errorf(\"system_account in config and operator JWT must be identical\")\n\t\t}\n\t} else if o.TrustedOperators[0].SystemAccount == _EMPTY_ {\n\t\t// In case the system account is neither defined in config nor in the first operator.\n\t\t// If it would be needed due to the nats account resolver, raise an error.\n\t\tswitch o.AccountResolver.(type) {\n\t\tcase *DirAccResolver, *CacheDirAccResolver:\n\t\t\treturn fmt.Errorf(\"using nats based account resolver - the system account needs to be specified in configuration or the operator jwt\")\n\t\t}\n\t}\n\n\tsrvMajor, srvMinor, srvUpdate, _ := versionComponents(VERSION)\n\tfor _, opc := range o.TrustedOperators {\n\t\tif major, minor, update, err := jwt.ParseServerVersion(opc.AssertServerVersion); err != nil {\n\t\t\treturn fmt.Errorf(\"operator %s expects version %s got error instead: %s\",\n\t\t\t\topc.Subject, opc.AssertServerVersion, err)\n\t\t} else if major > srvMajor {\n\t\t\treturn fmt.Errorf(\"operator %s expected major version %d > server major version %d\",\n\t\t\t\topc.Subject, major, srvMajor)\n\t\t} else if srvMajor > major {\n\t\t} else if minor > srvMinor {\n\t\t\treturn fmt.Errorf(\"operator %s expected minor version %d > server minor version %d\",\n\t\t\t\topc.Subject, minor, srvMinor)\n\t\t} else if srvMinor > minor {\n\t\t} else if update > srvUpdate {\n\t\t\treturn fmt.Errorf(\"operator %s expected update version %d > server update version %d\",\n\t\t\t\topc.Subject, update, srvUpdate)\n\t\t}\n\t}\n\t// If we have operators, fill in the trusted keys.\n\t// FIXME(dlc) - We had TrustedKeys before TrustedOperators. The jwt.OperatorClaims\n\t// has a DidSign(). Use that longer term. For now we can expand in place.\n\tfor _, opc := range o.TrustedOperators {\n\t\tif o.TrustedKeys == nil {\n\t\t\to.TrustedKeys = make([]string, 0, 4)\n\t\t}","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jwt.go#L115-L151","documentation":"The operator asserts a minimum server version. If its declared major version exceeds the running server's major version, validateOptions rejects the config because the server predates guarantees the operator requires.","triggerScenarios":"Operator JWT asserts e.g. 3.0.0 while running a 2.x nats-server; validateOptions compares versionComponents(VERSION) against the claim.","commonSituations":"Deploying an operator JWT generated with bleeding-edge tooling onto a production server running an older major release; rolling back the server binary without rolling back the operator.","solutions":["Upgrade nats-server to a version with a major >= the operator's assert","Or re-issue the operator JWT with a lower assertServerVersion appropriate for your deployment"],"exampleFix":"// before\nnats-server v2.10.x with operator asserting 3.0.0\n// after\nupgrade: go install github.com/nats-io/nats-server/v2@latest  (v3+)\n# or reissue operator with assert 2.10.0","handlingStrategy":"validation","validationCode":"// Go: compare asserted major against running server before startup\nsrvMajor, _, _, _ := versionComponents(VERSION)\nif major, _, _, err := jwt.ParseServerVersion(opc.AssertServerVersion); err == nil && major > srvMajor {\n    return fmt.Errorf(\"server too old for operator (major %d > %d)\", major, srvMajor)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin nsc and nats-server versions together in your release pipeline","Decode operator asserts in CI and compare against the deployed server version","Upgrade servers before distributing re-asserted operator JWTs"],"tags":["nats","jwt","version-mismatch","operator-mode"],"backgroundTag":"version-incompatible","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}