{"record":{"id":"54fac325564e0dc5","repo":"nats-io/nats-server","slug":"account-q-not-permitted-as-valid-account-option-f","errorCode":null,"errorMessage":"account %q not permitted as valid account option for auth callout for account %q","messagePattern":"account %q not permitted as valid account option for auth callout for account %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/auth_callout.go","lineNumber":184,"sourceCode":"\t\t}\n\n\t\t// the jwt issuer can be a signing key\n\t\tjwtIssuer := arc.Issuer\n\t\tif arc.IssuerAccount != _EMPTY_ {\n\t\t\tif !isOperatorMode {\n\t\t\t\t// this should be invalid - effectively it would allow the auth callout\n\t\t\t\t// to issue on another account which may be allowed given the configuration\n\t\t\t\t// where the auth callout account can handle multiple different ones..\n\t\t\t\treturn _EMPTY_, fmt.Errorf(\"error non operator mode account %q: attempted to use issuer_account\", account)\n\t\t\t}\n\t\t\tjwtIssuer = arc.IssuerAccount\n\t\t}\n\n\t\tif jwtIssuer != issuer {\n\t\t\tif !isOperatorMode {\n\t\t\t\treturn _EMPTY_, fmt.Errorf(\"wrong issuer for auth callout response on account %q, expected %q got %q\", account, issuer, jwtIssuer)\n\t\t\t} else if !acc.isAllowedAcount(jwtIssuer) {\n\t\t\t\treturn _EMPTY_, fmt.Errorf(\"account %q not permitted as valid account option for auth callout for account %q\",\n\t\t\t\t\tarc.Issuer, account)\n\t\t\t}\n\t\t}\n\t\treturn jwtIssuer, nil\n\t}\n\n\tgetExpirationAndAllowedConnections := func(arc *jwt.UserClaims, account string) (time.Duration, map[string]struct{}, error) {\n\t\tallowNow, expiration := validateTimes(arc)\n\t\tif !allowNow {\n\t\t\tc.Errorf(\"Outside connect times\")\n\t\t\treturn 0, nil, fmt.Errorf(\"authorized user on account %q outside of valid connect times\", account)\n\t\t}\n\n\t\tallowedConnTypes, err := convertAllowedConnectionTypes(arc.User.AllowedConnectionTypes)\n\t\tif err != nil {\n\t\t\tc.Debugf(\"%v\", err)\n\t\t\tif len(allowedConnTypes) == 0 {\n\t\t\t\treturn 0, nil, fmt.Errorf(\"authorized user on account %q using invalid connection type\", account)","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/auth_callout.go#L166-L202","documentation":"In operator mode, when the user JWT's issuer differs from the expected issuer, the server checks that the issuing account is listed in the target account's allowed_accounts (isAllowedAcount). If not, the callout is not permitted to issue users for that account and the response is rejected.","triggerScenarios":"Operator-mode deployment; the callout emits a user JWT signed by account X (cr.IssuerAccount/Issuer resolving to X), but X is not in the target account's allowed_accounts list, so acc.isAllowedAcount(jwtIssuer) fails.","commonSituations":"Adding a new callout/issuing account without adding it to allowed_accounts in the target account JWT; pushing updated account JWTs that dropped an allowed account entry.","solutions":["Add the issuing account's public key to the target account JWT's allowed_accounts list and re-push the account claim.","Verify which account signed the user JWT and that it matches an entry in allowed_accounts.","Ensure the updated account JWT is pushed to the resolver/JS account store so the server reloads it."],"exampleFix":"// before (account JWT)\n{ \"allowed_accounts\": [] }\n// after\n{ \"allowed_accounts\": [\"ADZJPGQFYly2...issuing-account-pub...\"] }","handlingStrategy":"validation","validationCode":"// before connecting users, confirm the issuing account is permitted:\n// decode target account JWT and check its allowed_accounts contains the issuer account public key","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep allowed_accounts in the target account JWT in sync with every callout issuer account.","Re-push account JWTs after edits and confirm the server picked them up.","Automate a check that each callout's issuer is in the target account's allowed list."],"tags":["auth-callout","operator-mode","jwt"],"backgroundTag":"auth-callout-issuer-not-allowed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}