{"record":{"id":"b67a97ac4b42fa9c","repo":"apache/hadoop","slug":"not-an-oob-status","errorCode":null,"errorMessage":"Not an OOB status: {}","messagePattern":"Not an OOB status: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java","lineNumber":4208,"sourceCode":"    oobTimeouts = new long[numOobTypes];\n\n    final String[] ele = getConf().get(DFS_DATANODE_OOB_TIMEOUT_KEY,\n        DFS_DATANODE_OOB_TIMEOUT_DEFAULT).split(\",\");\n    for (int i = 0; i < numOobTypes; i++) {\n      oobTimeouts[i] = (i < ele.length) ? Long.parseLong(ele[i]) : 0;\n    }\n  }\n\n  /**\n   * Get the timeout to be used for transmitting the OOB type\n   * @return the timeout in milliseconds\n   */\n  public long getOOBTimeout(Status status)\n      throws IOException {\n    if (status.getNumber() < Status.OOB_RESTART_VALUE ||\n        status.getNumber() > Status.OOB_RESERVED3_VALUE) {\n      // Not an OOB.\n      throw new IOException(\"Not an OOB status: \" + status);\n    }\n\n    return oobTimeouts[status.getNumber() - Status.OOB_RESTART_VALUE];\n  }\n\n  /**\n   * Start a timer to periodically write DataNode metrics to the log file. This\n   * behavior can be disabled by configuration.\n   *\n   */\n  protected void startMetricsLogger() {\n    long metricsLoggerPeriodSec = getConf().getInt(\n        DFS_DATANODE_METRICS_LOGGER_PERIOD_SECONDS_KEY,\n        DFS_DATANODE_METRICS_LOGGER_PERIOD_SECONDS_DEFAULT);\n\n    if (metricsLoggerPeriodSec <= 0) {\n      return;\n    }","sourceCodeStart":4190,"sourceCodeEnd":4226,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java#L4190-L4226","documentation":"getOOBTimeout maps an out-of-band pipeline Status (the numeric range Status.OOB_RESTART_VALUE..Status.OOB_RESERVED3_VALUE) to its ack/mirror timeout slot in oobTimeouts. Passing any ordinary Status (SUCCESS, ERROR, CHECKSUM_OK, ...) is a programming error: those have no OOB timeout, so the call is rejected before indexing the array.","triggerScenarios":"Calling DataNode.getOOBTimeout(status) with a non-OOB status - typically packet-ack handling code that forwards an arbitrary client/NN Status without first checking the OOB numeric range.","commonSituations":"Custom or modified DataTransfer pipeline code; newer Hadoop versions adding Status constants that old branching code does not recognize; copied code assuming every status is OOB.","solutions":["Check the numeric range before calling: status.getNumber() >= Status.OOB_RESTART_VALUE && status.getNumber() <= Status.OOB_RESERVED3_VALUE","Pass only the dedicated OOB constants (Status.OOB_RESTART, OOB_SOFT_CAPACITY, ...) to getOOBTimeout","Branch in pipeline code: OOB statuses -> getOOBTimeout; all others -> normal ack timeout"],"exampleFix":"// before\nlong timeout = datanode.getOOBTimeout(ack.getStatus()); // throws for SUCCESS/ERROR/etc.\n\n// after\nStatus s = ack.getStatus();\nlong timeout;\nif (s.getNumber() >= Status.OOB_RESTART_VALUE\n    && s.getNumber() <= Status.OOB_RESERVED3_VALUE) {\n  timeout = datanode.getOOBTimeout(s);\n} else {\n  timeout = normalAckTimeoutMs; // ordinary ack path\n}","handlingStrategy":"validation","validationCode":"boolean isOob = status.getNumber() >= Status.OOB_RESTART_VALUE\n    && status.getNumber() <= Status.OOB_RESERVED3_VALUE;\nif (isOob) {\n  long timeout = datanode.getOOBTimeout(status);\n} else {\n  // ordinary status: use the normal ack timeout, never getOOBTimeout\n}","typeGuard":"// Java predicate acting as a type guard over the Status enum range\nstatic boolean isOobStatus(Status s) {\n  return s != null\n      && s.getNumber() >= Status.OOB_RESTART_VALUE\n      && s.getNumber() <= Status.OOB_RESERVED3_VALUE;\n}","tryCatchPattern":null,"preventionTips":["Only pass the documented OOB constants (OOB_RESTART, OOB_SOFT_CAPACITY, ...) to getOOBTimeout","Centralize the OOB range check in one helper next to your ack-handling code","Add unit tests feeding every Status value through the branch to catch new enum constants"],"tags":["hadoop","hdfs","datanode","oob","status","validation"],"backgroundTag":"invalid-status-code","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}