{"record":{"id":"9546a920f58d6362","repo":"apache/hadoop","slug":"null-io-stream-from-reopen-of-reason","errorCode":null,"errorMessage":"Null IO stream from reopen of (\" + reason + \") \" + key","messagePattern":"Null IO stream from reopen of \\(\" \\+ reason \\+ \"\\) \" \\+ key","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosInputStream.java","lineNumber":559,"sourceCode":"    LOG.info(\n        \"reopen({}) for {} range[{}-{}], length={},\"\n            + \" contentLength={}, streamPosition={},\"\n            + \" nextReadPosition={}\",\n        key, reason, targetPos, contentRangeFinish,\n        length, contentLength, pos, nextReadPos);\n    try {\n      in = store.retrieve(\n          key, targetPos, contentRangeFinish,\n          fileMetaData);\n      contentRangeStart = targetPos;\n    } catch (Exception e) {\n      LOG.info(\n          \"native store retrieve failed reason : {}\",\n          e.getMessage());\n      closeStream(\"native store retrieve failed\");\n    }\n    if (in == null) {\n      throw new IOException(\n          \"Null IO stream from reopen of (\"\n              + reason + \") \" + key);\n    }\n    this.pos = targetPos;\n  }\n\n  /**\n   * Calculate the limit for a get request.\n   *\n   * @param targetPos position of the read\n   * @param length length of bytes requested; if less than\n   *               zero \"unknown\"\n   * @param fileContentLength total length of file\n   * @param readaheadLen current readahead value\n   * @return the absolute value of the limit of the request\n   *         (inclusive, last byte index).\n   */\n  private long calculateRequestLimit(","sourceCodeStart":541,"sourceCodeEnd":577,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosInputStream.java#L541-L577","documentation":"During reopen (lazy seek or read-failure recovery) BosInputStream calls store.retrieve(key, targetPos, contentRangeFinish, ...). If the call either returns null or throws — the catch block closes the stream, leaving in == null — it throws IOException 'Null IO stream from reopen of (<reason>) <key>'. The true cause is not in this exception; it appears only in the preceding LOG.info 'native store retrieve failed reason : ...' line.","triggerScenarios":"The recovery GET for a byte range fails or yields no content: object deleted or truncated mid-read, range no longer valid, auth/session-token expiry mid-stream, or a transient BOS 5xx during the reopen itself.","commonSituations":"Objects overwritten/deleted while a long task reads them; expired STS credentials during extended jobs; reading a file whose writer has not committed all data yet; flaky network to the BOS endpoint.","solutions":["Correlate with the server log line 'native store retrieve failed reason' — it carries the actual underlying error","Recover by reopening the file from scratch (new open() + seek to last good position) rather than reusing the dead stream","Verify the object still exists and its length is stable between open and read; forbid in-place rewrites of keys being read","Refresh long-lived credentials / re-issue STS tokens with longer TTL for long jobs"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"static boolean isReopenFailure(IOException e) {\n  return e.getMessage() != null && e.getMessage().startsWith(\"Null IO stream from reopen\");\n}","tryCatchPattern":"catch (IOException e) {\n  if (isReopenFailure(e)) {\n    in = fs.open(path);            // full reopen\n    ((BosInputStream) in.getWrappedStream()).seek(lastGoodPos);\n  } else { throw e; }\n}","preventionTips":["Check server logs for 'native store retrieve failed reason' to get the true cause","Never rewrite keys in place while readers are active","Refresh credentials before long reads; treat this as 'stream is dead, reopen'"],"tags":["bos","stream-reopen","read-failure","recovery","hadoop"],"backgroundTag":"stream-reopen-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}