thanos-io/thanos · error

closing snappy stream writer

Error message

closing snappy stream writer

What it means

Closing the snappy stream writer after encoding all postings failed. Close flushes the final snappy compressed block into compressedBuf; if it errors, the encoded postings cache entry is incomplete and is discarded rather than cached in corrupted form.

Solutions

  1. Check the wrapped underlying error for root cause
  2. Retry the cache encoding
  3. Increase memory if the failure happens during large postings flushes
Defensive patterns

Strategy: try-catch

Try / catch

b, err := diffVarintSnappyStreamedEncode(p, length)
if err != nil {
    if strings.Contains(err.Error(), "closing snappy stream writer") {
        log.WithError(errors.Unwrap(err)).Error("snappy stream close/flush failed")
        return retryEncoder(p, length)
    }
    return nil, err
}

Prevention

When it happens

Trigger: encodePostingsToCache -> diffVarintSnappyStreamedEncode after iterating all postings, when sw.Close() returns an error (flush/trailer write failure).

Common situations: Memory pressure during final flush; an already-failed underlying writer.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/1c5c2bd2db7328ab. Report an issue: GitHub.

Appendix: source

Thrown at pkg/store/postings_codec.go:128

		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")
	}

	return newStreamedDiffVarintPostings(input[len(codecHeaderStreamedSnappy):], disablePooling)
}

type streamedDiffVarintPostings struct {
	curSeries storage.SeriesRef

	err               error
	input, buf        []byte

View on GitHub (pinned to 35b8b99117)