{"record":{"id":"560dc1343a398410","repo":"uutils/coreutils","slug":"od-error-skip-past-end","errorCode":null,"errorMessage":"od-error-skip-past-end","messagePattern":"od-error-skip-past-end","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/uu/od/src/multifile_reader.rs","lineNumber":156,"sourceCode":"    /// special file (e.g. `/dev/null`, which can be skipped past its empty end).\n    /// Everything else - proc/sys files that report a bogus size, pipes, stdin -\n    /// is advanced by reading and discarding. Skipping past the end of the whole\n    /// input is an error, matching GNU `od`.\n    pub fn skip(&mut self, mut n_skip: u64) -> io::Result<()> {\n        while n_skip > 0 {\n            let Some(curr) = self.curr_file.as_mut() else {\n                break;\n            };\n            n_skip = skip_in_file(curr, n_skip)?;\n            if n_skip == 0 {\n                break;\n            }\n            // Current file is exhausted; continue skipping in the next one.\n            self.next_file();\n        }\n\n        if n_skip > 0 {\n            return Err(io::Error::new(\n                io::ErrorKind::UnexpectedEof,\n                translate!(\"od-error-skip-past-end\"),\n            ));\n        }\n        Ok(())\n    }\n}\n\n/// Skip up to `n_skip` bytes within a single file. Returns the number of bytes\n/// that still need to be skipped (0 if the skip landed inside this file, or\n/// the remainder if the file ended first).\nfn skip_in_file(curr: &mut CurrentReader, n_skip: u64) -> io::Result<u64> {\n    #[cfg(unix)]\n    if let CurrentReader::File(f) = curr\n        && let Ok(meta) = f.metadata()\n    {\n        let size = meta.len();\n        let blksize = uucore::fs::sane_blksize::sane_blksize_from_metadata(&meta);","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/uutils/coreutils/blob/325183372aaf86d8ae6feaf4f9548f74fe815102/src/uu/od/src/multifile_reader.rs#L138-L174","documentation":"od's MultifileReader::skip advances past n_skip bytes across the sequence of input files, advancing to the next file whenever the current one is exhausted. If, after consuming all input files, bytes remain to skip (n_skip > 0), the input is shorter than the requested skip amount and it returns an UnexpectedEof io::Error carrying this localized message. od throws it because byte offsets past the end of all inputs are undefined for output positioning.","triggerScenarios":"Running `od` with `--skip-bytes=N` (or equivalent skip option) where N exceeds the total size of all input files combined; also via open_input_peek_reader which calls skip during reader setup.","commonSituations":"Script computing skip offsets from a larger file but reading a truncated/rotated one; off-by-one or wrong unit (chars vs bytes) in skip arguments; piping/copying partial logs; combining multiple small files while assuming a larger total.","solutions":["Reduce the --skip-bytes value to at most the total input size (`stat -c %s file1 file2 | paste -sd+ | bc`).","Verify the input files are complete (re-download/re-copy truncated files) and check their sizes.","Check the skip unit — GNU od accepts suffixes like b (blocks of 512); a wrong unit can overshoot the file.","If skipping in a pipeline, ensure upstream producers actually wrote enough bytes before od reads."],"exampleFix":"// before\nod --skip-bytes=100000 small.txt   // file is only 4 KB\n// after\nsize=$(stat -c %s small.txt); od --skip-bytes=$((size > 100000 ? 100000 : size - 1)) small.txt","handlingStrategy":"validation","validationCode":"let total: u64 = std::fs::metadata(\"input.txt\")?.len();\nlet skip: u64 = 100000;\nif skip > total {\n    eprintln!(\"skip {skip} exceeds input size {total}\");\n    // clamp or load a larger input\n}","typeGuard":"fn skip_fits(skip: u64, inputs: &[&str]) -> std::io::Result<bool> {\n    let total: u64 = inputs.iter().try_fold(0u64, |acc, f| Ok(acc + std::fs::metadata(f)?.len()))?;\n    Ok(skip <= total)\n}","tryCatchPattern":"match od_result {\n    Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {\n        // skip past end: clamp skip to total input size and retry\n    }\n    r => r?,\n}","preventionTips":["Compute skip offsets from actual file sizes (stat), never hardcode","Watch od skip unit suffixes (b = 512-byte blocks) to avoid overshooting","Verify input file completeness (sizes/checksums) before offset-based reads"],"tags":["od","eof","skip-bytes","cli"],"backgroundTag":"skip-past-eof","analyzedSha":"325183372aaf86d8ae6feaf4f9548f74fe815102","analyzedAt":"2026-08-31T11:11:36.175Z","contentChangedAt":"2026-08-31T11:11:36.175Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}