nats-io/nats-server · warning
request body is empty
Error message
request body is empty
What it means
This ad-hoc error is created in server/events.go inside the account-claims update handler ($SYS > account claims update requests). When a JWT update request arrives with an empty message body, the server responds to the requester with 'jwt update error' and the reason 'request body is empty'. It is not an exported sentinel; it is only sent back as a response payload.
Source
Thrown at server/events.go:1662
}
// accountClaimUpdate will receive claim updates for accounts.
func (s *Server) accountClaimUpdate(sub *subscription, c *client, _ *Account, subject, resp string, hdr, msg []byte) {
if !s.EventsEnabled() {
return
}
var pubKey string
toks := strings.Split(subject, tsep)
if len(toks) == accUpdateTokensNew {
pubKey = toks[accReqAccIndex]
} else if len(toks) == accUpdateTokensOld {
pubKey = toks[accUpdateAccIdxOld]
} else {
s.Debugf("Received account claims update on bad subject %q", subject)
return
}
if len(msg) == 0 {
err := errors.New("request body is empty")
respondToUpdate(s, resp, pubKey, "jwt update error", err)
} else if claim, err := jwt.DecodeAccountClaims(string(msg)); err != nil {
respondToUpdate(s, resp, pubKey, "jwt update resulted in error", err)
} else if claim.Subject != pubKey {
err := errors.New("subject does not match jwt content")
respondToUpdate(s, resp, pubKey, "jwt update resulted in error", err)
} else if v, ok := s.accounts.Load(pubKey); !ok {
respondToUpdate(s, resp, pubKey, "jwt update skipped", nil)
} else if err := s.updateAccountWithClaimJWT(v.(*Account), string(msg)); err != nil {
respondToUpdate(s, resp, pubKey, "jwt update resulted in error", err)
} else {
respondToUpdate(s, resp, pubKey, "jwt updated", nil)
}
}
// processRemoteServerShutdown will update any affected accounts.
// Will update the remote count for clients.
// Lock assume held.View on GitHub (pinned to 3a66a489d2)
Solutions
- Ensure the JWT update request payload contains the account claims JWT before publishing to the system update subject.
- Check the publishing tool for empty reads (file read errors, empty env var) and fail fast before sending.
- Handle the 'jwt update error' response on the reply subject and log the reason to identify the caller sending empty bodies.
Example fix
// before
nc.Publish(updateSubj, []byte{}) // empty body
// after
if len(jwtBytes) == 0 {
return errors.New("refusing to publish empty jwt update")
}
nc.Publish(updateSubj, jwtBytes) Defensive patterns
Strategy: validation
Validate before calling
if len(msg) == 0 {
return errors.New("refusing to publish empty jwt update body")
} Try / catch
// subscribe to the reply subject and inspect the response reason
if resp.Error == "jwt update error" {
log.Printf("server rejected update: %s", resp.Reason)
} Prevention
- Check file/env sources for empty JWT content before publishing updates.
- Always request and check the response on the reply subject.
- Fail fast in tooling on zero-length payloads.
When it happens
Trigger: Publishing an account claims update request to the internal system subject with a zero-length payload (len(msg) == 0) via the system account update API (respondToUpdate with 'jwt update error').
Common situations: Tooling or operators publishing JWT updates over $SYS subjects that send an empty body due to a failed file read, encoding bug, or truncated message; custom JWT update automation bugs.
Related errors
- subject does not match jwt content
- 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/71b4128da647c168.
Report an issue: GitHub.