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

  1. Ensure the JWT update request payload contains the account claims JWT before publishing to the system update subject.
  2. Check the publishing tool for empty reads (file read errors, empty env var) and fail fast before sending.
  3. 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

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


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/71b4128da647c168. Report an issue: GitHub.