{"record":{"id":"04f771ca48b79e8d","repo":"nats-io/nats-server","slug":"not-trusted","errorCode":null,"errorMessage":"not trusted","messagePattern":"not trusted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/accounts.go","lineNumber":4373,"sourceCode":"\t}\n}\n\nfunc handleDeleteRequest(store *DirJWTStore, s *Server, msg []byte, reply string) {\n\tvar accIds []any\n\tvar subj, sysAccName string\n\tif sysAcc := s.SystemAccount(); sysAcc != nil {\n\t\tsysAccName = sysAcc.GetName()\n\t}\n\t// Only operator and operator signing key are allowed to delete\n\tgk, err := jwt.DecodeGeneric(string(msg))\n\tif err == nil {\n\t\tsubj = gk.Subject\n\t\tif store.deleteType == NoDelete {\n\t\t\terr = fmt.Errorf(\"delete must be enabled in server config\")\n\t\t} else if subj != gk.Issuer {\n\t\t\terr = fmt.Errorf(\"not self signed\")\n\t\t} else if _, ok := store.operator[gk.Issuer]; !ok {\n\t\t\terr = fmt.Errorf(\"not trusted\")\n\t\t} else if list, ok := gk.Data[\"accounts\"]; !ok {\n\t\t\terr = fmt.Errorf(\"malformed request\")\n\t\t} else if accIds, ok = list.([]any); !ok {\n\t\t\terr = fmt.Errorf(\"malformed request\")\n\t\t} else {\n\t\t\tfor _, entry := range accIds {\n\t\t\t\tif acc, ok := entry.(string); !ok ||\n\t\t\t\t\tacc == _EMPTY_ || !nkeys.IsValidPublicAccountKey(acc) {\n\t\t\t\t\terr = fmt.Errorf(\"malformed request\")\n\t\t\t\t\tbreak\n\t\t\t\t} else if acc == sysAccName {\n\t\t\t\t\terr = fmt.Errorf(\"not allowed to delete system account\")\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif err != nil {","sourceCodeStart":4355,"sourceCodeEnd":4391,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/accounts.go#L4355-L4391","documentation":"In nats-server, when a resolver processes an account-delete operator claim, it verifies the claim is self-signed by the operator and that the operator's public key appears in the server's trusted keys map (store.operator). The 'not trusted' error is returned when the deleting key's issuer is not among the server's configured trusted operator keys, so the delete request is rejected as coming from an untrusted operator.","triggerScenarios":"Calling the account-delete resolver flow with a delete claim whose Issuer (the operator signing key) is not present in the server's trusted operators / configured operator keys map. Also occurs when the server was configured with a different operator key than the one that signed the claim, or TrustedOperators changed after the claim was signed.","commonSituations":"Rotating operator signing keys without updating the server config; pointing a server at a different operator's resolver; using a dev key to sign claims for a production server; mixed-version clustered servers with different trusted key sets.","solutions":["Sign the delete claim with a signing key listed in the server's trusted operator keys (TrustedOperators / resolver operator config).","Add the operator public key that issued the claim to the server's operator config and reload/restart.","Regenerate the claim with the current operator key (nsc) so subject == issuer and the issuer is trusted."],"exampleFix":"// before\nerp, _ := nkeys.FromSeed(oldOperatorSeed)\nclaim.JWT, _ = claim.Encode(erp) // signed with untrusted key\n// after\nerp, _ := nkeys.FromSeed(currentOperatorSeed) // key trusted by server config\nclaim.JWT, _ = claim.Encode(erp)","handlingStrategy":"validation","validationCode":"pub, err := nkeys.FromPublicKey(operatorPubKey)\nif err != nil || operatorPubKey != claim.Issuer {\n    return fmt.Errorf(\"operator key %s not trusted by server\", claim.Issuer)\n}","typeGuard":null,"tryCatchPattern":"if err := pushDeleteClaim(claim); err != nil {\n    if strings.Contains(err.Error(), \"not trusted\") {\n        log.Fatalf(\"claim issuer %q not in server trusted keys; re-sign with trusted operator key\", claim.Issuer)\n    }\n}","preventionTips":["Always sign operator claims with the key listed in the server's operator config","Keep operator signing keys in sync across clusters and config management","Decode the claim and assert Subject == Issuer before pushing"],"tags":["nats","jwt","operator-claims","security"],"backgroundTag":"untrusted-operator-key","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}