thanos-io/thanos · warning
short-write for uvarint encoded byte
Error message
short-write for uvarint encoded byte
What it means
After writing a uvarint delta, the encoder checks that the writer consumed exactly uvarintSize bytes. A mismatch means the snappy stream writer accepted fewer bytes than supplied — a broken writer contract.
Solutions
- Report/investigate the non-conforming writer implementation
- Retry encoding; ensure the vendored snappy library is unmodified
Defensive patterns
Strategy: try-catch
Try / catch
b, err := diffVarintSnappyStreamedEncode(p, length)
if err != nil {
if strings.Contains(err.Error(), "short-write for uvarint encoded byte") {
return nil, fmt.Errorf("snappy writer contract violated: %w", err)
}
return nil, err
} Prevention
- Use only conforming io.Writer implementations in the compress path
- Keep vendored snappy code unmodified
- Treat short writes without error as a bug to report upstream
When it happens
Trigger: encodePostingsToCache -> diffVarintSnappyStreamedEncode when sw.Write returns written != uvarintSize; stock io.Writer implementations should return an error with short writes, making this an invariant breach.
Common situations: Non-conforming io.Writer wrapped by the compressor; practically never observed with stock snappy.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- short-write streamed snappy header
- writing streamed snappy header
- creating snappy compressor
- writing uvarint encoded byte
- closing snappy stream writer
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/d269c39d2f7bba56.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/store/postings_codec.go:119
uvarintEncodeBuf := make([]byte, binary.MaxVarintLen64)
sw, err := extsnappy.Compressor.Compress(compressedBuf)
if err != nil {
return nil, fmt.Errorf("creating snappy compressor: %w", err)
}
prev := storage.SeriesRef(0)
for p.Next() {
v := p.At()
if v < prev {
return nil, errors.Errorf("postings entries must be in increasing order, current: %d, previous: %d", v, prev)
}
uvarintSize := binary.PutUvarint(uvarintEncodeBuf, uint64(v-prev))
if written, err := sw.Write(uvarintEncodeBuf[:uvarintSize]); err != nil {
return nil, errors.Wrap(err, "writing uvarint encoded byte")
} else if written != uvarintSize {
return nil, errors.Wrap(err, "short-write for uvarint encoded byte")
}
prev = v
}
if p.Err() != nil {
return nil, p.Err()
}
if err := sw.Close(); err != nil {
return nil, errors.Wrap(err, "closing snappy stream writer")
}
return compressedBuf.Bytes(), nil
}
func diffVarintSnappyStreamedDecode(input []byte, disablePooling bool) (closeablePostings, error) {
if !isDiffVarintSnappyStreamedEncodedPostings(input) {
return nil, errors.New("header not found")
}View on GitHub (pinned to 35b8b99117)