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

  1. Report/investigate the non-conforming writer implementation
  2. 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

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


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)