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

  1. Restore the postings data from a healthy source (replica, backup, object storage).
  2. Check the offset/length calculations that produced this buffer; likely reading out of bounds into unrelated bytes.
  3. Re-compact the TSDB block to regenerate valid postings.
  4. 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

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


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 = nil

View on GitHub (pinned to 35b8b99117)