{"record":{"id":"23faa50303d609ab","repo":"thanos-io/thanos","slug":"got-bad-identifier-s","errorCode":null,"errorMessage":"got bad identifier %s","messagePattern":"got bad identifier (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/postings_codec.go","lineNumber":257,"sourceCode":"\tit.input = it.input[1:]\n\n\tif len(it.input) < 3 {\n\t\tit.err = io.ErrUnexpectedEOF\n\t\treturn false\n\t}\n\n\tchunkLen := int(it.input[0]) | int(it.input[1])<<8 | int(it.input[2])<<16\n\tit.input = it.input[3:]\n\n\tswitch chunkType {\n\tcase chunkTypeStreamIdentifier:\n\t\tconst magicBody = \"sNaPpY\"\n\t\tif chunkLen != len(magicBody) {\n\t\t\tit.err = fmt.Errorf(\"corrupted identifier\")\n\t\t\treturn false\n\t\t}\n\t\tif string(it.input[:len(magicBody)]) != magicBody {\n\t\t\tit.err = fmt.Errorf(\"got bad identifier %s\", string(it.input[:6]))\n\t\t\treturn false\n\t\t}\n\t\tit.input = it.input[6:]\n\t\tit.readSnappyIdentifier = true\n\t\treturn it.readNextChunk(nil)\n\tcase chunkTypeCompressedData:\n\t\tif !it.readSnappyIdentifier {\n\t\t\tit.err = fmt.Errorf(\"missing magic snappy marker\")\n\t\t\treturn false\n\t\t}\n\t\tif len(it.input) < 4 {\n\t\t\tit.err = io.ErrUnexpectedEOF\n\t\t\treturn false\n\t\t}\n\t\tchecksum := uint32(it.input[0]) | uint32(it.input[1])<<8 | uint32(it.input[2])<<16 | uint32(it.input[3])<<24\n\t\tif len(it.input) < chunkLen {\n\t\t\tit.err = io.ErrUnexpectedEOF\n\t\t\treturn false","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/postings_codec.go#L239-L275","documentation":"The postings iterator reads a Snappy-framed postings blob and expects the stream to begin with the 6-byte magic body \"sNaPpY\". This error is set when the first 6 bytes of the current chunk do not match that magic string, meaning the input is not the expected Snappy-identifier chunk or the framing is desynchronized. The iterator records the error and stops, so Next() returns false and Err() returns this error.","triggerScenarios":"Calling Next() on a postings iterator whose underlying byte slice does not start with the \"sNaPpY\" magic identifier; e.g. decoding data produced by another codec version, reading a truncated/shifted buffer, or passing raw uncompressed postings to diffVarintSnappyDecode-style iteration.","commonSituations":"Reading a postings file written by an older Prometheus version (pre-Snappy header), corruption during block download/repair, manually concatenated or offset buffers, or feeding non-postings binary data into the postings decoder.","solutions":["Regenerate the postings data by re-compacting the block with `promtool tsdb create-blocks-from` or letting TSDB rewrite the block so a valid Snappy identifier chunk is written.","Verify the buffer offset: make sure the slice passed to the decoder starts at the codec header, not shifted by earlier bytes.","Check that source data is intact (checksum the block files); restore from a healthy replica or backup.","Confirm client and server Prometheus versions agree on the postings codec (Snappy header) when sharing data."],"exampleFix":"// before: decoding a slice that may not carry the snappy magic\nit, err := NewPostingsCodecIterator(rawPostings)\n// after: verify the header first\nif !bytes.HasPrefix(rawPostings, []byte(\"sNaPpY\")) {\n    return nil, fmt.Errorf(\"postings blob lacks snappy header, len=%d\", len(rawPostings))\n}\nit, err := NewPostingsCodecIterator(rawPostings)","handlingStrategy":"validation","validationCode":"if !bytes.HasPrefix(blob, []byte(\"sNaPpY\")) {\n    return fmt.Errorf(\"postings blob missing snappy magic header\")\n}","typeGuard":"func hasSnappyMagic(b []byte) bool { return bytes.HasPrefix(b, []byte(\"sNaPpY\")) }","tryCatchPattern":null,"preventionTips":["Never slice off leading bytes of a postings blob before decoding.","Verify block checksums after download or copy.","Keep Prometheus versions consistent when sharing block data.","Regenerate old-format blocks with promtool before reading with new code."],"tags":["go","snappy","postings","corruption","codec"],"backgroundTag":"invalid-argument-format","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"}