{"record":{"id":"925a2e4483a33b0c","repo":"nats-io/nats-server","slug":"failed-to-read-original-block-from-disk-w","errorCode":null,"errorMessage":"failed to read original block from disk: %w","messagePattern":"failed to read original block from disk: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/filestore.go","lineNumber":7968,"sourceCode":"\t// If the block has been closed in the meantime, skip.\n\tif mb.closed {\n\t\treturn nil\n\t}\n\n\talg := mb.fs.fcfg.Compression\n\n\t// Open up the file block and read in the entire contents into memory.\n\t// One of two things will happen:\n\t// 1. The block will be compressed already and have a valid metadata\n\t//    header, in which case we do nothing.\n\t// 2. The block will be uncompressed, in which case we will compress it\n\t//    and then write it back out to disk, re-encrypting if necessary.\n\tmb.fs.dios.acquire()\n\torigBuf, err := os.ReadFile(mb.mfn)\n\tmb.fs.dios.release()\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read original block from disk: %w\", err)\n\t}\n\n\t// If the block is encrypted then we will need to decrypt it before\n\t// doing anything. We always encrypt after compressing because then the\n\t// compression can be as efficient as possible on the raw data, whereas\n\t// the encrypted ciphertext will not compress anywhere near as well.\n\t// The block encryption also covers the optional compression metadata.\n\tif err = mb.encryptOrDecryptIfNeeded(origBuf); err != nil {\n\t\treturn err\n\t}\n\n\tmeta := &CompressionInfo{}\n\tif _, err := meta.UnmarshalMetadata(origBuf); err != nil {\n\t\t// An error is only returned here if there's a problem with parsing\n\t\t// the metadata. If the file has no metadata at all, no error is\n\t\t// returned and the algorithm defaults to no compression.\n\t\treturn fmt.Errorf(\"failed to read existing metadata header: %w\", err)\n\t}","sourceCodeStart":7950,"sourceCodeEnd":7986,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L7950-L7986","documentation":"Returned during block recompression when reading the original block file (os.ReadFile on mb.mfn) fails inside a Dioscuri (dios) critical section. Recompression must load the full block into memory to decrypt/decompress and rewrite it; if the file cannot be read, the operation aborts with this wrapper.","triggerScenarios":"Calling stream/block recompression APIs (e.g. UpdateStream with a new compression algorithm) where the .blk file is unreadable — deleted, permission changed, or I/O error on the underlying device.","commonSituations":"Storage volume detached or full mid-operation; file removed by external cleanup scripts; running with a read-only filesystem; block file too large to read into available memory (OOM-adjacent failure).","solutions":["Check the wrapped cause: verify the block file exists and is readable by the server user","Free disk space / repair the mount before retrying compression","Ensure no external jobs delete files under the jetstream directory","Retry UpdateStream with the compression setting after storage is healthy"],"exampleFix":"// before: failing recompress on missing file\nls -l /path/jetstream/$ACC/streams/ORDERS/msgblk/3.blk\n# restore the file from backup, then re-run:\nnats stream update ORDERS --compression=s2","handlingStrategy":"retry","validationCode":"// Go: verify the block file is readable before recompression\nf, err := os.Open(blockPath)\nif err != nil {\n    return fmt.Errorf(\"block unreadable, skip compression change: %w\", err)\n}\nf.Close()","typeGuard":null,"tryCatchPattern":"err := js.UpdateStream(ctx, cfg) // compression change triggers recompress\nif err != nil && strings.Contains(err.Error(), \"failed to read original block\") {\n    if transientStorageErr(err) {\n        time.Sleep(retryBackoff)\n        return js.UpdateStream(ctx, cfg) // retry after mount/space restored\n    }\n    return err\n}","preventionTips":["Prevent external cron/cleanup jobs from touching jetstream directories","Confirm volume health before changing stream compression settings","Ensure enough RAM before compressing very large blocks","Keep a pre-change `nats stream backup`"],"tags":["jetstream","filestore","compression","io-error","recompression"],"backgroundTag":"file-read-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}