nats-io/nats-server · error
processRoutedMsgArgs Bad or Missing Size: '%s'
Error message
processRoutedMsgArgs Bad or Missing Size: '%s'
What it means
After parsing a routed MSG's size field, the server checks that the resulting size is non-negative. parseSize returns -1 for a non-numeric or negative size value, so a bad or missing final size field triggers this error. It protects the server from allocating based on garbage lengths.
Source
Thrown at server/route.go:446
c.pa.reply = args[3]
case '|':
c.pa.reply = nil
default:
return fmt.Errorf("processRoutedMsgArgs Bad or Missing Reply Indicator: '%s'", args[2])
}
// Grab size.
c.pa.szb = args[len(args)-1]
c.pa.size = parseSize(c.pa.szb)
// Grab queue names.
if c.pa.reply != nil {
c.pa.queues = args[4 : len(args)-1]
} else {
c.pa.queues = args[3 : len(args)-1]
}
}
if c.pa.size < 0 {
return fmt.Errorf("processRoutedMsgArgs Bad or Missing Size: '%s'", args)
}
// Common ones processed after check for arg length
c.pa.account = args[0]
c.pa.subject = args[1]
if len(an) > 0 {
c.pa.pacache = c.pa.subject
} else {
c.pa.pacache = arg[:len(args[0])+len(args[1])+1]
}
return nil
}
// processInboundRoutedMsg is called to process an inbound msg from a route.
func (c *client) processInboundRoutedMsg(msg []byte) {
// Update statistics
c.in.msgs++
// The msg includes the CR_LF, so pull back out for accounting.View on GitHub (pinned to 3a66a489d2)
Solutions
- Ensure the last field of the routed MSG line is the decimal byte size of the payload
- Fix the emitter to compute size as len(payload) exactly
- Trace the raw protocol line to see which sender produced the malformed frame
- Check route/TLS links for corruption and keep cluster servers on compatible versions
Example fix
// before "MSG foo + reply 5 abc\r\n" // 'abc' where size should be // after "MSG foo + reply 5\r\n" + payload
Defensive patterns
Strategy: validation
Validate before calling
// Validate the size field parses to a non-negative integer before sending
size, err := strconv.Atoi(lastField)
if err != nil || size < 0 {
return fmt.Errorf("bad size field %q", lastField)
}
if size != len(payload) {
return fmt.Errorf("size %d != payload len %d", size, len(payload))
} Prevention
- Compute sizes with len() instead of hand-counting bytes
- Keep size as the final field of the MSG line
- Alert on server-side bad-size parse errors to catch broken emitters quickly
When it happens
Trigger: Final arg of a routed MSG is not a valid non-negative integer (e.g. 'abc', '-5', or empty), causing parseSize to return -1.
Common situations: Corrupt cluster traffic, custom publishers writing wrong size fields, off-by-one in hand-built protocol emitters that put a queue name where the size belongs, or truncated frames after network errors.
Related errors
- processRoutedHeaderMsgArgs Header Size larger then TotalSize
- processRoutedMsgArgs Parse Error: '%s'
- processRoutedMsgArgs Bad or Missing Reply Indicator: '%s'
- invalid publish message, variable header exceeds remaining l
- restore for stream '%s > %s' requires reply subject for each
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/b39da840e20593b4.
Report an issue: GitHub.