{"record":{"id":"9858c2325136c946","repo":"influxdata/influxdb","slug":"io-error-0-serialize","errorCode":null,"errorMessage":"IO error: {0}","messagePattern":"IO error: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"influxdb3_wal/src/serialize.rs","lineNumber":26,"sourceCode":"use std::io::Cursor;\nuse std::mem::size_of;\nuse thiserror::Error;\n\n#[derive(Debug, Error)]\npub enum Error {\n    #[error(\"Invalid wal file identifier\")]\n    InvalidWalFile,\n\n    #[error(\"WAL file too small: expected at least {expected} bytes, but got {actual} bytes\")]\n    WalFileTooSmall { expected: usize, actual: usize },\n\n    #[error(\"crc32 checksum mismatch\")]\n    Crc32Mismatch,\n\n    #[error(\"bitcode error: {0}\")]\n    Bitcode(#[from] bitcode::Error),\n\n    #[error(\"IO error: {0}\")]\n    Io(#[from] std::io::Error),\n\n    #[error(\"try from slice error {0}\")]\n    TryFromSlice(#[from] std::array::TryFromSliceError),\n}\n\npub(crate) type Result<T, E = Error> = std::result::Result<T, E>;\n\n/// The first bytes written into a wal file to identify it and its version.\nconst FILE_TYPE_IDENTIFIER: &[u8] = b\"idb3.001\";\n\n#[inline(always)]\npub fn verify_file_type_and_deserialize(b: Bytes) -> Result<WalContents> {\n    let contents = b.to_vec();\n\n    let pos = FILE_TYPE_IDENTIFIER.len();\n    const CHECKSUM_LEN: usize = size_of::<u32>();\n    let min_file_size = pos + CHECKSUM_LEN;","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_wal/src/serialize.rs#L8-L44","documentation":"serialize::Error::Io wraps a std::io::Error encountered while reading a WAL file (via #[from]). The serializer reads the file bytes before parsing; any filesystem-level failure — permission denied, file missing mid-read, I/O errors from the disk — surfaces as this variant with the OS error message embedded.","triggerScenarios":"Reading a WAL file during replay/verify when the file is unreadable: wrong permissions, deleted between listing and read, disk I/O error, or a device failure while streaming bytes into verify_file_type_and_deserialize.","commonSituations":"WAL directory owned by a different user after running under two service accounts; NFS/network mounts dropping; EIO on failing disks; a cleanup job deleting files while the reader scans the directory.","solutions":["Check file permissions and ownership on the WAL directory/files (the inner io::Error kind will say PermissionDenied).","Re-run after fixing the transient storage issue (remount, disk replacement); replay is idempotent up to the failure point.","Exclude the WAL directory from aggressive cleanup jobs that race with the reader.","Look at the wrapped io::Error message to distinguish not-found vs permission vs hardware error and fix accordingly."],"exampleFix":"# before\nsudo -u otheruser influxdb3 ...   # Io(Os { code: 13, kind: PermissionDenied })\n# after: run the reader as the WAL directory owner\nsudo -u influxdb3 influxdb3 ...","handlingStrategy":"try-catch","validationCode":"// check readability of every WAL file before replay\nfn readable(path: &Path) -> bool {\n    std::fs::File::open(path).and_then(|f| f.metadata()).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match verify_file_type_and_deserialize(&bytes) {\n    Err(serialize::Error::Io(e)) if e.kind() == std::io::ErrorKind::PermissionDenied => {\n        // fix ownership/permissions, then retry replay\n    }\n    other => other?,\n}","preventionTips":["Run all reader/writer processes under the same service account owning the WAL dir.","Exclude the WAL directory from cleanup jobs racing with replay.","Monitor disk health (EIO) and remount/replace failing storage promptly."],"tags":["rust","wal","io","filesystem"],"backgroundTag":"file-read-failed","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}