{"record":{"id":"ba3cf912c2c3fb36","repo":"clockworklabs/SpacetimeDB","slug":"error-reading-commit-header-e","errorCode":null,"errorMessage":"error reading commit header: {e}","messagePattern":"error reading commit header: (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/commitlog/src/commit.rs","lineNumber":91,"sourceCode":"\n                Ok(Some(Self {\n                    min_tx_offset,\n                    epoch: Commit::DEFAULT_EPOCH,\n                    n,\n                    len,\n                }))\n            }\n        }\n    }\n\n    fn decode_v1<R: Read>(mut reader: R) -> io::Result<Option<Self>> {\n        let mut hdr = [0; Self::LEN];\n        if let Err(e) = reader.read_exact(&mut hdr) {\n            if e.kind() == io::ErrorKind::UnexpectedEof {\n                return Ok(None);\n            }\n\n            return Err(io::Error::new(e.kind(), format!(\"error reading commit header: {e}\")));\n        }\n        match &mut hdr.as_slice() {\n            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(None),\n            buf => {\n                let min_tx_offset = buf.get_u64().map_err(|e| decode_header_error(e, \"min_tx_offset\"))?;\n                let epoch = buf.get_u64().map_err(|e| decode_header_error(e, \"epoch\"))?;\n                let n = buf.get_u16().map_err(|e| decode_header_error(e, \"n\"))?;\n                let len = buf.get_u32().map_err(|e| decode_header_error(e, \"len\"))?;\n\n                Ok(Some(Self {\n                    min_tx_offset,\n                    epoch,\n                    n,\n                    len,\n                }))\n            }\n        }\n    }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/commitlog/src/commit.rs#L73-L109","documentation":"When decoding a commit from the commitlog, the reader first reads the fixed 14-byte header; an UnexpectedEof there is treated as a clean end of the log (Ok(None)). Any other I/O error while reading the header is re-wrapped with 'error reading commit header', preserving the original error kind. In practice this indicates an environmental problem such as permissions or a device error, not a normal end-of-log.","triggerScenarios":"Reading a commit whose 14-byte header read fails with a non-UnexpectedEof error: EACCES or EIO on a segment file, storage detached mid-read.","commonSituations":"Disk or permission trouble on the db directory while the host reads its log; files chowned or chmodded under a running process.","solutions":["Check OS logs (dmesg, journalctl) for device/IO errors and test the disk","Verify ownership and permissions of the commitlog repository files for the host process","Restore the repository from a snapshot or backup if the medium is failing"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use std::io;\nloop {\n    match commit.decode(&mut reader) {\n        Ok(None) => break, // clean end of log\n        Ok(Some(c)) => { /* handle commit */ }\n        Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,\n        Err(e) => return Err(e), // UnexpectedEof is normalized to Ok(None) by the library;\n                                 // any error here is environmental — surface it, don't retry\n    }\n}","preventionTips":["Grant the host process stable ownership of its db directory","Monitor disk health; investigate any EIO or EACCES immediately","Never chmod, chown, or move log files under a running host"],"tags":["rust","io","commitlog","disk"],"backgroundTag":"disk-read-error","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}