{"record":{"id":"e56ca174c9032cc4","repo":"juicedata/juicefs","slug":"unable-to-skip-s-bytes-position-s-filesize-s","errorCode":null,"errorMessage":"Unable to skip %s bytes (position=%s, fileSize=%s): %s","messagePattern":"Unable to skip (.+?) bytes \\(position=(.+?), fileSize=(.+?)\\): (.+?)","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"warning","filePath":"sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java","lineNumber":1213,"sourceCode":"      } else {\n        buf.position(0);\n        buf.limit(0);\n        position = p;\n      }\n    }\n\n    public synchronized void skipNBytes(long n) throws IOException {\n      if (buf == null) {\n        throw new IOException(\"stream was closed\");\n      }\n\n      if (n <= 0) {\n        return;\n      }\n\n      long np = position + n;\n      if (np > fileLen) {\n        throw new EOFException(String.format(\"Unable to skip %s bytes (position=%s, fileSize=%s): %s\", n, position, fileLen, np));\n      }\n      position = np;\n    }\n    @Override\n    public synchronized long skip(long n) throws IOException {\n      if (n < 0)\n        return -1;\n      if (buf == null)\n        throw new IOException(\"stream was closed\");\n      long pos = getPos();\n      if (pos + n > fileLen) {\n        n = fileLen - pos;\n      }\n      seek(pos + n);\n      return n;\n    }\n\n    @Override","sourceCodeStart":1195,"sourceCodeEnd":1231,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java#L1195-L1231","documentation":"This EOFException is thrown by FileInputStream.skipNBytes in JuiceFileSystemImpl when the requested skip would advance the read position past the end of the file. The library tracks the current position and the file length captured at open(); if position + n exceeds fileLen, the skip is impossible, so it fails instead of silently clamping (unlike skip(), which clamps). The message reports the requested byte count, current position, file size, and the resulting target offset.","triggerScenarios":"Calling FSDataInputStream.skipNBytes(n) (directly or via the FileSystem API) where position + n > fileLen — e.g. skipping past EOF after reading near the end of a truncated or concurrently-shrinking file, or using a stale file length.","commonSituations":"Spark/MapReduce record readers trusting a stale split length while the file was truncated or overwritten between listing and read; application logic computing skip offsets from a different (larger) file version; using skipNBytes with a length taken from a directory listing that has since changed.","solutions":["Catch EOFException around skipNBytes and treat it as end-of-data (it is the documented signal that the file end was reached).","Reopen the file and re-fetch its length before computing skip offsets if the file may be modified concurrently.","Use skip(n) instead of skipNBytes(n) if you want clamping-to-EOF semantics rather than an exception.","Verify the caller's expected record/split lengths against the actual file size (fs.getFileStatus(path).getLen()) before skipping."],"exampleFix":"// before\nin.skipNBytes(remaining); // throws EOFException near EOF\n// after\ntry {\n  in.skipNBytes(remaining);\n} catch (EOFException e) {\n  // reached end of file earlier than expected; stop reading\n  break;\n}","handlingStrategy":"try-catch","validationCode":"long fileLen = fs.getFileStatus(path).getLen();\nlong pos = in.getPos();\nif (pos + n > fileLen) {\n  throw new EOFException(\"skip would pass EOF: pos=\" + pos + \" n=\" + n + \" len=\" + fileLen);\n}\nin.skipNBytes(n);","typeGuard":null,"tryCatchPattern":"try {\n  in.skipNBytes(n);\n} catch (EOFException e) {\n  // end-of-file reached; handle as normal termination\n  LOG.warn(\"skip hit EOF: {}\", e.getMessage());\n}","preventionTips":["Re-check file length (getFileStatus) before large skips on files that may change.","Prefer skip(n) when clamping to EOF is acceptable behavior.","Compute skip offsets from the stream's own getPos(), not stale listing metadata.","Treat EOFException from skipNBytes as an expected signal, not a crash."],"tags":["java","io","eof","hadoop-filesystem"],"backgroundTag":"value-out-of-range","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}