thanos-io/thanos · error
invalid chunk type
Error message
invalid chunk type %v
What it means
The chunk header byte was > 0xfd, which is not a valid Snappy-style chunk type (0xfe/0xff are reserved as invalid by the Snappy framing format). This signals the stream is corrupt or not a postings-codec stream, so iteration stops with this error.
Solutions
- Restore the postings data from a healthy source (replica, backup, object storage).
- Check the offset/length calculations that produced this buffer; likely reading out of bounds into unrelated bytes.
- Re-compact the TSDB block to regenerate valid postings.
- Confirm no external tool rewrote the block files.
Defensive patterns
Strategy: validation
Validate before calling
if len(blob) > 0 && blob[0] > 0xfd {
return fmt.Errorf("invalid leading chunk type byte: %#x", blob[0])
} Prevention
- Guard length/offset calculations to avoid reading past valid data.
- Treat any decode error as block corruption; restore from replica.
- Do not merge or append postings blobs with ad-hoc tools.
When it happens
Trigger: Next() reads a chunk type byte > 0xfd, usually because the iterator is consuming garbage bytes after corruption, an incorrect offset, or a truncated/overwritten buffer.
Common situations: Reading past the end of valid data (length confusion), corrupted block files, or tools that appended/merged postings blobs incorrectly.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- got bad identifier
- unsupported chunk type
- missing magic snappy marker
- mismatched checksum (got , expected )
- snappy decode
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/9be062a14afa1aa6.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/store/postings_codec.go:353
// and not cause any problems.
if len(remainder) > 0 {
remainderCopy := make([]byte, 0, len(remainder))
remainderCopy = append(remainderCopy, remainder...)
remainder = remainderCopy
}
if len(remainder) > 0 {
it.db.B = append(remainder, uncompressedData...)
} else {
it.db.B = uncompressedData
}
default:
if chunkType <= 0x7f {
it.err = fmt.Errorf("unsupported chunk type %v", chunkType)
return false
}
if chunkType > 0xfd {
it.err = fmt.Errorf("invalid chunk type %v", chunkType)
return false
}
}
it.input = it.input[chunkLen:]
return true
}
func (it *streamedDiffVarintPostings) Next() bool {
// Continue reading next chunks until there is at least binary.MaxVarintLen64.
// If we cannot add any more chunks then return false.
for {
val := it.db.Uvarint64()
if it.db.Err() != nil {
if !it.readNextChunk(it.db.B) {
return false
}
it.db.E = nilView on GitHub (pinned to 35b8b99117)