nats-io/nats-server · error
account jwt not found
Error message
account jwt not found
What it means
In the NATS server, account JWTs are fetched from an upstream resolver (e.g. an operator's account resolver) via an internal request/reply round trip. When the reply arrives but the response message is empty, the server sets err to errors.New("account jwt not found") in server/accounts.go (~line 4776) instead of a JWT. This means the lookup completed but no JWT payload was returned for that account name.
Source
Thrown at server/accounts.go:4776
select {
case respC <- clone:
default:
}
}
}
s.sendInternalMsg(accountLookupRequest, replySubj, nil, []byte{})
quit := s.quitCh
s.mu.Unlock()
var err error
var theJWT string
select {
case <-quit:
err = errors.New("fetching jwt failed due to shutdown")
case <-time.After(timeout):
err = errors.New("fetching jwt timed out")
case m := <-respC:
if len(m) == 0 {
err = errors.New("account jwt not found")
} else if err = res.Store(name, string(m)); err == nil {
theJWT = string(m)
}
}
s.mu.Lock()
delete(replies, replySubj)
s.mu.Unlock()
close(respC)
return theJWT, err
}
func NewCacheDirAccResolver(path string, limit int64, ttl time.Duration, opts ...DirResOption) (*CacheDirAccResolver, error) {
if limit <= 0 {
limit = 1_000
}
store, err := NewExpiringDirJWTStore(path, false, true, HardDelete, 0, limit, true, ttl, nil)
if err != nil {
return nil, errView on GitHub (pinned to 3a66a489d2)
Solutions
- Verify the account JWT actually exists in the resolver backend: for a nats resolver, run 'nsc describe account' / check the resolver store; for a dir resolver, confirm the JWT file exists in the resolver directory for that account public key.
- Re-push the account: run 'nsc push -a <account>' (or 'nsc push -A' for all accounts) so the resolver has the JWT.
- Check the resolver configuration (resolver: URL / directory) in the server config — a wrong URL or directory silently yields empty responses.
- Confirm the account public key used for the lookup matches the subject in the account JWT.
- If running a memory resolver, ensure the account was embedded in the operator JWT and the operator JWT was updated on the server.
Example fix
// before: config points at an empty resolver store resolver: URL(nats://resolver:4222) // after: push the account JWT so lookups succeed // nsc push --url nats://resolver:4222 -a ACCTPUBLICKEY resolver: URL(nats://resolver:4222)
Defensive patterns
Strategy: retry
Validate before calling
// before relying on resolver lookup, confirm the JWT is retrievable
claims, err := jwt.DecodeAccountClaims(pubKey) // or load from nsc store
if err != nil {
return fmt.Errorf("account %s has no JWT in the store: %w", pubKey, err)
}
if claims.Subject != pubKey {
return fmt.Errorf("account %s: subject mismatch, re-push JWT", pubKey)
} Try / catch
jwt, err := resolver.Fetch(pubKey)
if err != nil {
if strings.Contains(err.Error(), "account jwt not found") {
// push the JWT then retry once
if perr := pushAccountJWT(pubKey); perr == nil {
jwt, err = resolver.Fetch(pubKey)
}
}
if err != nil { return err }
} Prevention
- Run 'nsc push -A' after every account change so the resolver store is current.
- Validate resolver URL/directory settings before starting the server.
- Log and alert on resolver fetch failures at startup (server prints resolver errors).
- Never hand-edit account public keys in configs; generate them with nsc.
When it happens
Trigger: Calling an API that resolves an account JWT (via Fetch, the resolver's Store/Load path, or server startup fetching accounts) when the response channel receives a zero-length message. This happens with a resolver backend (mem/dir/nats) that has no JWT for the requested account, or when the upstream 'accs' subscription replies with an empty payload.
Common situations: Misconfigured resolver URL pointing at a resolver service that doesn't know the account; an operator account JWT not yet pushed/uploaded to the resolver; using a memory resolver without the account embedded in the operator JWT; a fresh cluster where account claims were never uploaded; typos in the account public key (NKEY) used for lookup.
Related errors
- no operator key 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
- subject has exceeded number of tokens limit
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/cc722a00b7e5083d.
Report an issue: GitHub.