{"record":{"id":"6399f313db5ba915","repo":"rustfs/rustfs","slug":"unexpectedeof-6399f3","errorCode":"UnexpectedEof","errorMessage":"Unexpected EOF","messagePattern":"Unexpected EOF","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/filemeta/src/error.rs","lineNumber":142,"sourceCode":"            Error::UuidParse(s) => Error::UuidParse(s.clone()),\n            Error::Unexpected => Error::Unexpected,\n        }\n    }\n}\n\nimpl From<std::io::Error> for Error {\n    fn from(e: std::io::Error) -> Self {\n        match e.kind() {\n            std::io::ErrorKind::UnexpectedEof => Error::Unexpected,\n            _ => Error::Io(e),\n        }\n    }\n}\n\nimpl From<Error> for std::io::Error {\n    fn from(e: Error) -> Self {\n        match e {\n            Error::Unexpected => std::io::Error::new(std::io::ErrorKind::UnexpectedEof, \"Unexpected EOF\"),\n            Error::Io(e) => e,\n            _ => std::io::Error::other(e.to_string()),\n        }\n    }\n}\n\nimpl From<rmp_serde::decode::Error> for Error {\n    fn from(e: rmp_serde::decode::Error) -> Self {\n        Error::RmpSerdeDecode(e.to_string())\n    }\n}\n\nimpl From<rmp_serde::encode::Error> for Error {\n    fn from(e: rmp_serde::encode::Error) -> Self {\n        Error::RmpSerdeEncode(e.to_string())\n    }\n}\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/rustfs/rustfs/blob/9e6e02ea09c86bedf44c7bd64a74ea02a0cff1de/crates/filemeta/src/error.rs#L124-L160","documentation":"Conversion pair in rustfs-filemeta's Error type: any std::io::Error of kind UnexpectedEof maps to Error::Unexpected (and back to io UnexpectedEof with message 'Unexpected EOF'). It surfaces whenever a metadata (xl.meta) read ends before the expected number of bytes — the file/stream is shorter than the header or stat size claims.","triggerScenarios":"read_xl_meta* / FileMeta::load paths read an xl.meta file whose stat size says N bytes but the read returns EOF earlier (truncated file, concurrent writer, disk fault); the io error propagates through From<io::Error> and collapses into Error::Unexpected.","commonSituations":"Power loss mid-write leaving a truncated xl.meta; disk sectors going bad; copying a pool with rsync while it is being written; inspecting an xl.meta partially downloaded; heal reading a damaged shard.","solutions":["Run a heal on the bucket/object so erasure coding rebuilds the truncated xl.meta from other shards","If all shards are truncated, restore the object from backup or re-upload it","Check disk health (SMART) on the node reporting the EOF — repeated UnexpectedEof on one drive indicates failing hardware","Avoid file-level copies of a live pool; snapshot or quiesce before copying"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use rustfs_filemeta::error::Error;\nmatch FileMeta::load(&buf) {\n    Err(Error::Unexpected) => {\n        // xl.meta shorter than expected: heal the object or restore from replicas;\n        // do not retry the same read — the file on disk is truncated\n    }\n    other => other?,\n}","preventionTips":["Run periodic heal scans so truncated metadata is rebuilt before reads hit it","Monitor SMART/disk errors on nodes that repeatedly produce UnexpectedEof","Never file-copy a live pool; quiesce or snapshot first"],"tags":["metadata","xl-meta","truncation","io","data-corruption"],"backgroundTag":"truncated-metadata-file","analyzedSha":"9e6e02ea09c86bedf44c7bd64a74ea02a0cff1de","analyzedAt":"2026-08-16T20:34:17.560Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}