{"record":{"id":"087276bdfc6ae92e","repo":"nats-io/nats-server","slug":"failed-to-parse-message-sequence-d-invalid-heade","errorCode":null,"errorMessage":"failed to parse message sequence %d: invalid header length","messagePattern":"failed to parse message sequence (.+?): invalid header length","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/stream_backup.go","lineNumber":507,"sourceCode":"\t\t\tstoredSizeRaw = fileStoreMsgSizeRaw(len(hdr.Name), int(hdr.HeaderSize), int(hdr.PayloadSize))\n\t\t}\n\t\tif storedSizeRaw > math.MaxInt64 {\n\t\t\treturn nil, fmt.Errorf(\"snapshot message bytes exceed reserved restore size\")\n\t\t}\n\t\tstoredSize := int64(storedSizeRaw)\n\t\tif additional := storedSize - restoreRemaining; additional > 0 {\n\t\t\tjsa.updateUsage(tier, cfg.Storage, additional)\n\t\t\trestoreRemaining += additional\n\t\t\tif err := checkUsageLimits(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tbuf, err := io.ReadAll(tr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read message sequence %d: %w\", seq, err)\n\t\t}\n\t\tif hdr.HeaderSize > int64(len(buf)) {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse message sequence %d: invalid header length\", seq)\n\t\t}\n\t\tif int64(len(buf)) != declaredSize {\n\t\t\treturn nil, fmt.Errorf(\"failed to read message sequence %d: unexpected payload size\", seq)\n\t\t}\n\t\tsubj := hdr.Name\n\t\tmhdr := buf[:hdr.HeaderSize]\n\t\tmsg := buf[hdr.HeaderSize : hdr.HeaderSize+hdr.PayloadSize]\n\t\tif seq <= lseq {\n\t\t\treturn nil, fmt.Errorf(\"message sequence %d out of order\", seq)\n\t\t}\n\t\t// We could have deleted messages since the last message we stored, if so\n\t\t// we should work out what the gap is and skip those sequences.\n\t\tif gap := seq - lseq - 1; gap > 0 {\n\t\t\tif err := store.SkipMsgs(lseq+1, gap); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to process gap: %w\", err)\n\t\t\t}\n\t\t}\n\t\tlseq = seq","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream_backup.go#L489-L525","documentation":"RestoreStreamV2 reads each backed-up message sequence from the restore reader and validates the per-message block before storing it. This error means the block's declared header size (hdr.HeaderSize) is larger than the actual bytes read for that message block, so the header cannot be extracted from the payload buffer. It indicates a corrupt or malformed stream backup file where the message block layout does not match what was written.","triggerScenarios":"Reading a message sequence from the backup stream where hdr.HeaderSize exceeds the length of the buffer returned by io.ReadAll(tr); typically caused by a truncated/corrupted backup archive, bit rot, or a backup written by an incompatible encoder.","commonSituations":"Restoring a stream backup file that was truncated mid-transfer (partial rsync/S3 upload), editing or re-compressing a backup file, restoring across incompatible nats-server versions, or disk corruption on the archive.","solutions":["Verify the backup file integrity (checksum) and re-transfer/re-create the backup from the source stream","Confirm the backup was created with the same or compatible nats-server version that supports the v2 backup format","Check that the transfer pipeline (compression, proxies) did not truncate or modify the file byte-for-byte","Retry the restore with the original unmodified backup archive"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"info, err := fi.Stat()\nif err != nil || info.Size() < expectedMinSize { return fmt.Errorf(\"backup file too small or unreadable\") }\n// verify checksum against the value recorded at backup time\nif got := sha256File(path); got != wantChecksum { return fmt.Errorf(\"backup checksum mismatch\") }","typeGuard":null,"tryCatchPattern":"mset, err := srv.RestoreStreamV2(...)\nif err != nil && strings.Contains(err.Error(), \"invalid header length\") {\n    // treat as corrupt backup: do not retry with same file\n}","preventionTips":["Checksum backup files at creation and verify before restore","Transfer backups in binary-safe modes only","Never edit or recompress backup archives","Use matching nats-server versions for backup and restore"],"tags":["jetstream","restore","corruption","backup"],"backgroundTag":"corrupt-backup-file","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}