apache/hadoop · error · IOException

Offset={} out of the range [0, {}); {}, path={}

Error message

Offset={} out of the range [0, {}); {}, path={}

What it means

RouterWebHdfsMethods.chooseDatanode validates the client-supplied offset for WebHDFS OPEN: it must satisfy 0 <= offset < fileLength (when length > 0). A negative offset, or one at/after EOF, throws IOException with the offending offset, the valid range, the op and the path. This mirrors the NameNode-side check but runs on the Router before it picks a replica DataNode for the redirect.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterWebHdfsMethods.java:521

      } else if (op == PutOpParam.Op.CREATE && !ns.equals(resolvedNs)) {
        // for CREATE, the dest dn should be in the resolved ns
        excludes.add(dn);
      }
    }

    if (op == GetOpParam.Op.OPEN ||
        op == PostOpParam.Op.APPEND ||
        op == GetOpParam.Op.GETFILECHECKSUM) {
      // Choose a datanode containing a replica
      final ClientProtocol cp = getRpcClientProtocol();
      final HdfsFileStatus status = cp.getFileInfo(path);
      if (status == null) {
        throw new FileNotFoundException("File " + path + " not found.");
      }
      final long len = status.getLen();
      if (op == GetOpParam.Op.OPEN) {
        if (openOffset < 0L || (openOffset >= len && len > 0)) {
          throw new IOException("Offset=" + openOffset
              + " out of the range [0, " + len + "); " + op + ", path=" + path);
        }
      }

      if (len > 0) {
        final long offset = op == GetOpParam.Op.OPEN ? openOffset : len - 1;
        final LocatedBlocks locations = cp.getBlockLocations(path, offset, 1);
        final int count = locations.locatedBlockCount();
        if (count > 0) {
          LocatedBlock location0 = locations.get(0);
          return bestNode(location0.getLocations(), excludes);
        }
      }
    }

    return getRandomDatanode(dns, excludes);
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Clamp the request to 0 <= offset < len, fetching the current length via GETFILESTATUS first
  2. Treat offset == len as clean EOF on the client side instead of issuing a request
  3. Re-read the file status after concurrent writes/truncations and recompute offsets from the fresh length

Example fix

// before
InputStream in = openPath(urlWithOffset("offset=" + offset)); // offset may be >= len

// after
HdfsFileStatus st = getFileInfo(path);
long len = st.getLen();
if (offset < 0 || (offset >= len && len > 0)) {
  offset = Math.max(0, len - 1); // or signal EOF to the caller
}
InputStream in = openPath(urlWithOffset("offset=" + offset));
Defensive patterns

Strategy: validation

Validate before calling

HdfsFileStatus st = cp.getFileInfo(path);
long len = (st == null) ? 0 : st.getLen();
boolean valid = offset >= 0 && (len == 0 || offset < len);
if (!valid) {
  // treat as EOF or bad request; do not issue the WebHDFS OPEN
}

Try / catch

catch (IOException e) {
  if (e.getMessage().startsWith("Offset=")
      && e.getMessage().contains("out of the range")) {
    // refresh file length and re-clamp offset before retrying once
  }
}

Prevention

When it happens

Trigger: WebHDFS OPEN with offset=<negative> or offset >= length; reading at EOF instead of using length as end-of-stream signal; clients computing offsets from a stale file length after the file was truncated/rewritten.

Common situations: Custom readers that request offset == len to 'probe' EOF; files truncated concurrently so the cached length is now larger than reality; unit tests passing 0-length and boundary offsets.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/61386a53c536000a. Report an issue: GitHub.