{"record":{"id":"83ab0e1eb23a9b74","repo":"nats-io/nats-server","slug":"failed-to-decompress-block-w","errorCode":null,"errorMessage":"failed to decompress block: %w","messagePattern":"failed to decompress block: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/filestore.go","lineNumber":6884,"sourceCode":"\t\t\t\tpurged++\n\t\t\t\tbytes += uint64(rl)\n\t\t\t}\n\t\t}\n\t}\n\n\t// If the block is compressed/encrypted then we have to load it into memory\n\t// and decompress/decrypt it, truncate it and then write it back out.\n\t// Otherwise, truncate the file itself and close the descriptor.\n\tif mb.cmp != NoCompression || mb.bek != nil {\n\t\tbuf, err := mb.loadBlock(nil)\n\t\tif err != nil {\n\t\t\treturn 0, 0, fmt.Errorf(\"failed to load block from disk: %w\", err)\n\t\t}\n\t\tif err = mb.encryptOrDecryptIfNeeded(buf); err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tif buf, err = mb.decompressIfNeeded(buf); err != nil {\n\t\t\treturn 0, 0, fmt.Errorf(\"failed to decompress block: %w\", err)\n\t\t}\n\t\tbuf = buf[:eof]\n\t\tcopy(mb.lchk[0:], buf[len(buf)-checksumSize:])\n\t\t// We did decompress but don't recompress the truncated buffer here since we're the last block\n\t\t// and would otherwise have compressed data and allow to write uncompressed data in the same block.\n\t\tif err = mb.atomicOverwriteFile(buf, false); err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t} else if mb.mfd != nil {\n\t\tif err = mb.mfd.Truncate(eof); err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tif err = mb.mfd.Sync(); err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\t// Update our checksum.\n\t\tvar lchk [8]byte\n\t\tif _, err = mb.mfd.ReadAt(lchk[:], eof-8); err != nil {","sourceCodeStart":6866,"sourceCodeEnd":6902,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L6866-L6902","documentation":"Wraps an error from mb.decompressIfNeeded while truncating the last block of a stream: the block was loaded from disk successfully but could not be decompressed/decrypted back to its original buffer. Indicates corrupted compressed bytes or a decompressor failure, so the truncate operation aborts.","triggerScenarios":"Truncating a compressed last block (truncateMsgs) where the loaded buffer fails decompression — corrupt compressed payload, wrong compression algorithm recorded for the block, or truncated data with a stale checksum.","commonSituations":"Block files damaged by crashes or disk faults; mismatched server versions writing different compression formats; restored backups inconsistent with metadata.","solutions":["Check the wrapped decompression cause and whether the block's compression flag matches the data","Reset the affected stream (delete its block files) to force recreation if data loss is acceptable","Restore the store directory from a consistent offline backup","Align server versions across upgrades to keep compression formats consistent"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Go: distinguish load vs decompress failures when truncating last block\nif _, _, err := truncateLastBlock(mb, eof); err != nil {\n    if strings.Contains(err.Error(), \"failed to decompress block\") {\n        // compressed payload corrupt: restore backup or reset stream\n    }\n    return err\n}","preventionTips":["Keep compression settings and server versions consistent across upgrades","Monitor storage for corruption; checksum volumes periodically","Restore stores only from consistent offline backups","Accept stream reset as recovery when no backup exists"],"tags":["compression","corruption","truncation","filestore"],"backgroundTag":"block-decompress-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}