clockworklabs/SpacetimeDB · error · std::io::Error

error reading commit header

Error message

error reading commit header: {e}

What it means

Low-level commitlog error raised while decoding a commit header (Header::decode_v1 in the commitlog crate). The decoder reads the fixed-size v1 header (Header::LEN = 22 bytes: min_tx_offset u64, epoch u64, n u16, len u32); a clean end-of-file at that boundary is normal and returns Ok(None) so preallocated zeroed segments are allowed. Any other I/O failure is re-wrapped with this message, preserving the underlying io::ErrorKind.

Solutions

  1. Check the data directory: permissions on segment files, disk health (dmesg/SMART), free space.
  2. Ensure no second process (another node, a truncating backup job, manual tooling) mutates segment files while the log is being read.
  3. If the media is damaged, restore the commitlog directory from a snapshot or replica.
Defensive patterns

Strategy: try-catch

Validate before calling

// Fail fast if segment files are not readable before replay
let meta = std::fs::metadata(&segment_path)?;
anyhow::ensure!(meta.permissions().readonly() == false, "segment file is read-only");

Try / catch

match Header::decode(&mut reader) {
    Ok(Some(hdr)) => { /* process commit */ }
    Ok(None) => {} // clean end of log (EOF at header boundary or zeroed preallocated bytes)
    Err(e) => {
        // UnexpectedEof is already normalized to Ok(None) by the library;
        // anything reaching here is a real storage fault - surface it, do not retry blindly.
        return Err(e.into());
    }
}

Prevention

When it happens

Trigger: Replaying or opening a commitlog segment when the storage read fails partway through the header byte range with something other than UnexpectedEof - e.g. PermissionDenied, device/IO errors, or a failing network filesystem under the data directory.

Common situations: Data-directory permissions changed under a running node; failing or disconnecting disks/NFS; another process truncating or deleting segment files during replay.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@9e0d92412f (2026-08-20). Data as JSON: /api/errors/ba3cf912c2c3fb36. Report an issue: GitHub.

Appendix: source

Thrown at crates/commitlog/src/commit.rs:92

                Ok(Some(Self {
                    min_tx_offset,
                    epoch: Commit::DEFAULT_EPOCH,
                    n,
                    len,
                }))
            }
        }
    }

    fn decode_v1<R: Read>(mut reader: R) -> io::Result<Option<Self>> {
        let mut hdr = [0; Self::LEN];
        if let Err(e) = reader.read_exact(&mut hdr) {
            if e.kind() == io::ErrorKind::UnexpectedEof {
                return Ok(None);
            }

            return Err(io::Error::new(e.kind(), format!("error reading commit header: {e}")));
        }
        match &mut hdr.as_slice() {
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(None),
            buf => {
                let min_tx_offset = buf.get_u64().map_err(|e| decode_header_error(e, "min_tx_offset"))?;
                let epoch = buf.get_u64().map_err(|e| decode_header_error(e, "epoch"))?;
                let n = buf.get_u16().map_err(|e| decode_header_error(e, "n"))?;
                let len = buf.get_u32().map_err(|e| decode_header_error(e, "len"))?;

                Ok(Some(Self {
                    min_tx_offset,
                    epoch,
                    n,
                    len,
                }))
            }
        }
    }

View on GitHub (pinned to 9e0d92412f)