{"record":{"id":"693697026bf8184c","repo":"apache/hadoop","slug":"tried-to-read-byte-s-past-the-limit-at-offset","errorCode":null,"errorMessage":"Tried to read {} byte(s) past the limit at offset {}","messagePattern":"Tried to read (.+?) byte\\(s\\) past the limit at offset (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java","lineNumber":1355,"sourceCode":"   * Stream wrapper that keeps track of the current stream position.\n   * \n   * This stream also allows us to set a limit on how many bytes we can read\n   * without getting an exception.\n   */\n  public static class PositionTrackingInputStream extends FilterInputStream\n      implements StreamLimiter {\n    private long curPos = 0;\n    private long markPos = -1;\n    private long limitPos = Long.MAX_VALUE;\n\n    public PositionTrackingInputStream(InputStream is) {\n      super(is);\n    }\n\n    private void checkLimit(long amt) throws IOException {\n      long extra = (curPos + amt) - limitPos;\n      if (extra > 0) {\n        throw new IOException(\"Tried to read \" + amt + \" byte(s) past \" +\n            \"the limit at offset \" + limitPos);\n      }\n    }\n    \n    @Override\n    public int read() throws IOException {\n      checkLimit(1);\n      int ret = super.read();\n      if (ret != -1) curPos++;\n      return ret;\n    }\n\n    @Override\n    public int read(byte[] data) throws IOException {\n      checkLimit(data.length);\n      int ret = super.read(data);\n      if (ret > 0) curPos += ret;\n      return ret;","sourceCodeStart":1337,"sourceCodeEnd":1373,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java#L1337-L1373","documentation":"PositionTrackingInputStream.checkLimit bounds every read while FSEditLogOp.Reader decodes an op frame: the reader calls limiter.setLimit(maxOpSize) before each op (FSEditLogOp.java:5229), so a single op can never read past maxOpSize bytes (dfs.namenode.max.op.size, default 50MB). The throw means the stream's length or checksum fields directed a read beyond that bound: the anti-OOM guard for garbage data, per the comment at FSEditLogOp.java:5242.","triggerScenarios":"Replaying or scanning (scanEditLog, EditLogFileInputStream.scanEditLog) a corrupt or torn edit segment where a bogus length field makes one op appear larger than maxOpSize; also possible on genuinely huge ops if the limit was lowered below their real size.","commonSituations":"Crash-torn final segment; disk corruption; dfs.namenode.max.op.size tuned far below actual op sizes (for example very long paths or large xattr ops).","solutions":["Treat the segment as corrupt: validate with 'hdfs oev' and recover with 'hdfs namenode -recover'","Only if logs legitimately contain ops larger than 50MB, raise dfs.namenode.max.op.size; note that a garbage length field will still fail checksum verification","Restore a consistent fsimage plus edits from backup if recovery cannot salvage the segment"],"exampleFix":"# before: replay trips the per-op size limiter\nhdfs --daemon start namenode   # Tried to read 33554433 byte(s) past the limit ...\n\n# after: confirm corruption, then recover\nhdfs oev -i <segment> -o /tmp/check.xml -p xml   # parse fails at the same op\nhdfs namenode -recover\n# alternative for genuinely huge ops only:\n#   <property><name>dfs.namenode.max.op.size</name><value>104857600</value></property>","handlingStrategy":"try-catch","validationCode":"hdfs oev -i <segment> -o /tmp/check.xml -p xml\n# the parser applies the same maxOpSize bound and checksum checks before replay does","typeGuard":null,"tryCatchPattern":"// mirror scanEditLog: bound the damage, log, resync, continue only with progress\ntry {\n  op = in.readOp();\n} catch (IOException ioe) {          // includes 'Tried to read ... past the limit'\n  LOG.warn(\"Bad op at offset \" + in.getPosition(), ioe);\n  in.resync();                        // skip to the next boundary; stop if no progress\n}","preventionTips":["Leave dfs.namenode.max.op.size at its 50MB default unless valid ops are larger","Ensure clean NameNode shutdowns; torn tails are the main source of oversized frames","Monitor disk health on NameNode and JournalNode hosts"],"tags":["hdfs","namenode","edit-log","corruption","max-op-size","oom-guard","stream-limit"],"backgroundTag":"max-op-size-exceeded","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}