nats-io/nats-server · error
auth callout service returned an error: %v
Error message
auth callout service returned an error: %v
What it means
The auth callout response JWT itself contained a non-empty Error field, meaning the callout service explicitly refused or failed the authorization request. The server surfaces that error text verbatim to the connecting client's auth flow. This is the designed mechanism for a callout to deny a connection with a reason.
Source
Thrown at server/auth_callout.go:137
vr := jwt.CreateValidationResults()
cr.Validate(vr)
if len(vr.Issues) > 0 {
return nil, fmt.Errorf("authorization response had validation errors: %v", vr.Issues[0])
}
// the subject is the user id
if cr.Subject != pub {
return nil, errors.New("auth callout violation: auth callout response is not for expected user")
}
// check the audience to be the server ID
if cr.Audience != s.info.ID {
return nil, errors.New("auth callout violation: auth callout response is not for server")
}
// check if had an error message from the auth account
if cr.Error != _EMPTY_ {
return nil, fmt.Errorf("auth callout service returned an error: %v", cr.Error)
}
// if response is encrypted none of this is needed
if isOperatorMode && !encrypted {
pkStr := cr.Issuer
if cr.IssuerAccount != _EMPTY_ {
pkStr = cr.IssuerAccount
}
if pkStr != account {
if _, ok := acc.hasIssuer(pkStr); !ok {
return nil, errors.New("auth callout signing key is unknown")
}
}
}
return jwt.DecodeUserClaims(cr.Jwt)
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Read the %v message — it is the callout service's own denial reason — and fix credentials/permissions on the client or rules in the callout service.
- Check the auth callout service's logs to see why it set cr.Error.
- Verify the external identity backend the callout consults is healthy.
- If the denial is wrong, update the callout service's authorization logic or account mapping.
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.Contains(err.Error(), "auth callout service returned an error") {
// denial reason follows ': ' — surface it to the operator/client
log.Printf("callout denied connection: %s", err)
} Prevention
- Inspect the callout service's own error message in the wrapped error.
- Monitor the callout's upstream identity backend health.
- Log callout decisions server-side to correlate denials with clients.
When it happens
Trigger: The callout service publishes an AuthorizationResponseClaims with cr.Error set to a non-empty message (e.g. "user not found", "account suspended") in reply to an authorization request.
Common situations: User credentials rejected by the external auth backend; upstream identity provider outage causing the callout to report an error; misconfigured callout rules denying valid users.
Related errors
- operators do not allow authorization callouts to be configur
- auth callout violation: %q on account %q
- error decrypting auth callout response on account %q: %v
- authorization response had validation errors: %v
- error non operator mode account %q: attempted to use issuer_
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/9eb82f4396e4bf7d.
Report an issue: GitHub.