nats-io/nats-server · error
processHeaderPub Bad or Missing Total Size: %q
Error message
processHeaderPub Bad or Missing Total Size: %q
What it means
The total size field of an HMSG message parsed to a negative value. parseSize() returns -1 when the number is missing, non-numeric, or overflows int64, so the server cannot determine the total message length and rejects the protocol op.
Source
Thrown at server/client.go:2926
c.pa.size = parseSize(args[2])
c.pa.hdb = args[1]
c.pa.szb = args[2]
case 4:
c.pa.subject = args[0]
c.pa.reply = args[1]
c.pa.hdr = parseSize(args[2])
c.pa.size = parseSize(args[3])
c.pa.hdb = args[2]
c.pa.szb = args[3]
default:
return fmt.Errorf("processHeaderPub Parse Error: %q", arg)
}
if c.pa.hdr < 0 {
return fmt.Errorf("processHeaderPub Bad or Missing Header Size: %q", arg)
}
// If number overruns an int64, parseSize() will have returned a negative value
if c.pa.size < 0 {
return fmt.Errorf("processHeaderPub Bad or Missing Total Size: %q", arg)
}
if c.pa.hdr > c.pa.size {
return fmt.Errorf("processHeaderPub Header Size larger then TotalSize: %q", arg)
}
maxPayload := atomic.LoadInt32(&c.mpay)
// Use int64() to avoid int32 overrun...
if maxPayload != jwt.NoLimit && int64(c.pa.size) > int64(maxPayload) {
// If we are given the remaining read buffer (since we do blind reads
// we may have the beginning of the message header/payload), we will
// look for the tracing header and if found, we will generate a
// trace event with the max payload ingress error.
// Do this only for CLIENT connections.
if c.kind == CLIENT && c.pa.hdr > 0 && len(remaining) > 0 {
hdr := remaining[:min(len(remaining), c.pa.hdr)]
c.sendMsgTraceIngressErrEvent(hdr, ErrMaxPayload)
}
c.maxPayloadViolation(c.pa.size, maxPayload)
return ErrMaxPayloadView on GitHub (pinned to 3a66a489d2)
Solutions
- Fix the client to compute total size as header size + payload size using a correct integer type
- Ensure the size token is a plain decimal number with no sign, spaces, or suffixes
- Inspect server debug logs / packet capture to find the malformed HMSG line and the client
Example fix
// before HMSG subj reply 5 -1 // after HMSG subj reply 5 12
Defensive patterns
Strategy: validation
Validate before calling
total := len(header) + len(payload)
if total < 0 || total > math.MaxInt32 {
return errors.New("HMSG total size out of range")
} Type guard
func isNonNegativeSize(token string) (int64, bool) {
n, err := strconv.ParseInt(token, 10, 64)
return n, err == nil && n >= 0
} Prevention
- Compute total size in an int64 and cap it before sending
- Never send -1 or signed sentinel values as sizes
- Keep header and payload sizes consistent with what is actually written
When it happens
Trigger: Client sends `HMSG <subject> <reply> <hdr> <total>` where total-size is non-numeric, negative, or exceeds int64 (e.g. 99999999999999999999), making c.pa.size < 0.
Common situations: Buggy client implementations computing the total size incorrectly, integer overflow when concatenating header+payload sizes, corrupted frames over the wire.
Related errors
- processPub Bad or Missing Size: %q
- processHeaderPub Bad or Missing Header Size: %q
- processHeaderPub Header Size larger then TotalSize: %q
- processPub Parse Error: %q
- processSub Parse Error: %q
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/4714bbc351f599fc.
Report an issue: GitHub.