{"record":{"id":"d269c39d2f7bba56","repo":"thanos-io/thanos","slug":"short-write-for-uvarint-encoded-byte","errorCode":null,"errorMessage":"short-write for uvarint encoded byte","messagePattern":"short-write for uvarint encoded byte","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/store/postings_codec.go","lineNumber":119,"sourceCode":"\tuvarintEncodeBuf := make([]byte, binary.MaxVarintLen64)\n\n\tsw, err := extsnappy.Compressor.Compress(compressedBuf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating snappy compressor: %w\", err)\n\t}\n\n\tprev := storage.SeriesRef(0)\n\tfor p.Next() {\n\t\tv := p.At()\n\t\tif v < prev {\n\t\t\treturn nil, errors.Errorf(\"postings entries must be in increasing order, current: %d, previous: %d\", v, prev)\n\t\t}\n\n\t\tuvarintSize := binary.PutUvarint(uvarintEncodeBuf, uint64(v-prev))\n\t\tif written, err := sw.Write(uvarintEncodeBuf[:uvarintSize]); err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"writing uvarint encoded byte\")\n\t\t} else if written != uvarintSize {\n\t\t\treturn nil, errors.Wrap(err, \"short-write for uvarint encoded byte\")\n\t\t}\n\n\t\tprev = v\n\t}\n\tif p.Err() != nil {\n\t\treturn nil, p.Err()\n\t}\n\tif err := sw.Close(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"closing snappy stream writer\")\n\t}\n\n\treturn compressedBuf.Bytes(), nil\n}\n\nfunc diffVarintSnappyStreamedDecode(input []byte, disablePooling bool) (closeablePostings, error) {\n\tif !isDiffVarintSnappyStreamedEncodedPostings(input) {\n\t\treturn nil, errors.New(\"header not found\")\n\t}","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/postings_codec.go#L101-L137","documentation":"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.","triggerScenarios":"encodePostingsToCache -> diffVarintSnappyStreamedEncode when sw.Write returns written != uvarintSize; stock io.Writer implementations should return an error with short writes, making this an invariant breach.","commonSituations":"Non-conforming io.Writer wrapped by the compressor; practically never observed with stock snappy.","solutions":["Report/investigate the non-conforming writer implementation","Retry encoding; ensure the vendored snappy library is unmodified"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"b, err := diffVarintSnappyStreamedEncode(p, length)\nif err != nil {\n    if strings.Contains(err.Error(), \"short-write for uvarint encoded byte\") {\n        return nil, fmt.Errorf(\"snappy writer contract violated: %w\", err)\n    }\n    return nil, err\n}","preventionTips":["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"],"tags":["snappy","encoding","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}