nats-io/nats-server · error
validation errors: %v
Error message
validation errors: %v
What it means
claimValidate validates an *jwt.AccountClaims using the nkeys/jwt library's ValidationResults. If any blocking validation errors are found (expired/invalid dates, bad subject/public key pairing, malformed limits, etc.), the server wraps all of them in 'validation errors: %v' and rejects the account claim update.
Source
Thrown at server/accounts.go:4436
strict = opts.TrustedOperators[0].StrictSigningKeyUsage
if !strict {
keys[opts.TrustedOperators[0].Subject] = struct{}{}
}
for _, key := range opts.TrustedOperators[0].SigningKeys {
keys[key] = struct{}{}
}
}
if len(keys) == 0 {
return _EMPTY_, nil, false, fmt.Errorf("no operator key found")
}
return op, keys, strict, nil
}
func claimValidate(claim *jwt.AccountClaims) error {
vr := &jwt.ValidationResults{}
claim.Validate(vr)
if vr.IsBlocking(false) {
return fmt.Errorf("validation errors: %v", vr.Errors())
}
return nil
}
func removeCb(s *Server, pubKey string) {
v, ok := s.accounts.Load(pubKey)
if !ok {
return
}
a := v.(*Account)
s.Debugf("Disable account %s due to remove", pubKey)
a.mu.Lock()
// lock out new clients
a.msubs = 0
a.mpay = 0
a.mconns = 0
a.mleafs = 0
a.updated = time.Now()View on GitHub (pinned to 3a66a489d2)
Solutions
- Read the %v list in the error — it enumerates the exact validation failures — and fix the claim accordingly.
- Re-issue the account JWT with nsc (or current nats.go jwt package) and re-push it.
- Ensure server clock/NTP is correct and both nsc and nats-server are up to date.
Example fix
// before
claim.Expires = time.Now().Add(-time.Hour).Unix() // already expired
// after
claim.Expires = time.Now().Add(24 * time.Hour).Unix()
vr := &jwt.ValidationResults{}
claim.Validate(vr)
if vr.IsBlocking(false) { /* fix before publishing */ } Defensive patterns
Strategy: validation
Validate before calling
vr := &jwt.ValidationResults{}
claim.Validate(vr)
if vr.IsBlocking(false) {
return fmt.Errorf("claim invalid: %v", vr.Errors())
} Try / catch
if err := pushAccountJWT(tok); err != nil && strings.Contains(err.Error(), "validation errors") {
var vr jwt.ValidationResults
fmt.Println(err) // enumerated causes: fix each, then re-push
} Prevention
- Validate claims locally with jwt.ValidationResults before publishing
- Keep clocks NTP-synced on signing and serving hosts
- Keep nsc and nats-server versions current
When it happens
Trigger: Publishing an account JWT whose claims fail jwt.AccountClaims.Validate with blocking results — expired token, subject not a valid account key, issuer mismatch, negative/invalid limits or imports/exports issues.
Common situations: Clock skew between the signing host and server; expired accounts after revocation/expiry windows; hand-edited JWTs; old nats-server versions not accepting newer claim fields; nsc/jwt library version mismatches.
Related errors
- malformed request
- account jwt not found
- auth callout violation: auth callout response is not for exp
- auth callout violation: auth callout response is not for ser
- auth callout signing key is unknown
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/86ed9a487fb3d818.
Report an issue: GitHub.