{"record":{"id":"f100411337847a71","repo":"nats-io/nats-server","slug":"processheaderpub-header-size-larger-then-totalsize","errorCode":null,"errorMessage":"processHeaderPub Header Size larger then TotalSize: %q","messagePattern":"processHeaderPub Header Size larger then TotalSize: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/client.go","lineNumber":2929,"sourceCode":"\tcase 4:\n\t\tc.pa.subject = args[0]\n\t\tc.pa.reply = args[1]\n\t\tc.pa.hdr = parseSize(args[2])\n\t\tc.pa.size = parseSize(args[3])\n\t\tc.pa.hdb = args[2]\n\t\tc.pa.szb = args[3]\n\tdefault:\n\t\treturn fmt.Errorf(\"processHeaderPub Parse Error: %q\", arg)\n\t}\n\tif c.pa.hdr < 0 {\n\t\treturn fmt.Errorf(\"processHeaderPub Bad or Missing Header Size: %q\", arg)\n\t}\n\t// If number overruns an int64, parseSize() will have returned a negative value\n\tif c.pa.size < 0 {\n\t\treturn fmt.Errorf(\"processHeaderPub Bad or Missing Total Size: %q\", arg)\n\t}\n\tif c.pa.hdr > c.pa.size {\n\t\treturn fmt.Errorf(\"processHeaderPub Header Size larger then TotalSize: %q\", arg)\n\t}\n\tmaxPayload := atomic.LoadInt32(&c.mpay)\n\t// Use int64() to avoid int32 overrun...\n\tif maxPayload != jwt.NoLimit && int64(c.pa.size) > int64(maxPayload) {\n\t\t// If we are given the remaining read buffer (since we do blind reads\n\t\t// we may have the beginning of the message header/payload), we will\n\t\t// look for the tracing header and if found, we will generate a\n\t\t// trace event with the max payload ingress error.\n\t\t// Do this only for CLIENT connections.\n\t\tif c.kind == CLIENT && c.pa.hdr > 0 && len(remaining) > 0 {\n\t\t\thdr := remaining[:min(len(remaining), c.pa.hdr)]\n\t\t\tc.sendMsgTraceIngressErrEvent(hdr, ErrMaxPayload)\n\t\t}\n\t\tc.maxPayloadViolation(c.pa.size, maxPayload)\n\t\treturn ErrMaxPayload\n\t}\n\tif c.opts.Pedantic && !IsValidLiteralSubject(bytesToString(c.pa.subject)) {\n\t\tc.sendErr(\"Invalid Publish Subject\")","sourceCodeStart":2911,"sourceCodeEnd":2947,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/client.go#L2911-L2947","documentation":"Client protocol parse guard: in an HPUB protocol line the parsed header size (c.pa.hdr) exceeds the parsed total payload size (c.pa.size), which is impossible for a well-formed message and indicates a malformed or corrupted protocol line.","triggerScenarios":"Client sends `HMSG <subject> <reply> <hdr> <total>` with hdr > total, e.g. `HMSG s r 20 10`, so c.pa.hdr > c.pa.size.","commonSituations":"Client bug swapping or miscalculating the two size fields, header built larger than the buffer used to compute total size, hand-written protocol frames in tests/scripts.","solutions":["Fix the client so total size is always >= header size (total = hdr + payload len)","Check for swapped arguments in the client's HMSG formatting code","Enable NATS server debug logging to see the offending protocol line"],"exampleFix":"// before\nHMSG subj reply 20 10\n// after\nHMSG subj reply 5 12","handlingStrategy":"validation","validationCode":"if hdrSize > totalSize {\n    return errors.New(\"header size cannot exceed total size\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Assert hdr <= total in the client before writing the frame","Total = header length + payload length; derive one from the other","Add unit tests that frame HMSG messages with headers"],"tags":["protocol","parsing","validation"],"backgroundTag":"nats-protocol-parse-error","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}