apache/hadoop · error · IOException

Not an OOB status: {}

Error message

Not an OOB status: {}

What it means

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.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java:4208

    oobTimeouts = new long[numOobTypes];

    final String[] ele = getConf().get(DFS_DATANODE_OOB_TIMEOUT_KEY,
        DFS_DATANODE_OOB_TIMEOUT_DEFAULT).split(",");
    for (int i = 0; i < numOobTypes; i++) {
      oobTimeouts[i] = (i < ele.length) ? Long.parseLong(ele[i]) : 0;
    }
  }

  /**
   * Get the timeout to be used for transmitting the OOB type
   * @return the timeout in milliseconds
   */
  public long getOOBTimeout(Status status)
      throws IOException {
    if (status.getNumber() < Status.OOB_RESTART_VALUE ||
        status.getNumber() > Status.OOB_RESERVED3_VALUE) {
      // Not an OOB.
      throw new IOException("Not an OOB status: " + status);
    }

    return oobTimeouts[status.getNumber() - Status.OOB_RESTART_VALUE];
  }

  /**
   * Start a timer to periodically write DataNode metrics to the log file. This
   * behavior can be disabled by configuration.
   *
   */
  protected void startMetricsLogger() {
    long metricsLoggerPeriodSec = getConf().getInt(
        DFS_DATANODE_METRICS_LOGGER_PERIOD_SECONDS_KEY,
        DFS_DATANODE_METRICS_LOGGER_PERIOD_SECONDS_DEFAULT);

    if (metricsLoggerPeriodSec <= 0) {
      return;
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Check the numeric range before calling: status.getNumber() >= Status.OOB_RESTART_VALUE && status.getNumber() <= Status.OOB_RESERVED3_VALUE
  2. Pass only the dedicated OOB constants (Status.OOB_RESTART, OOB_SOFT_CAPACITY, ...) to getOOBTimeout
  3. Branch in pipeline code: OOB statuses -> getOOBTimeout; all others -> normal ack timeout

Example fix

// before
long timeout = datanode.getOOBTimeout(ack.getStatus()); // throws for SUCCESS/ERROR/etc.

// after
Status s = ack.getStatus();
long timeout;
if (s.getNumber() >= Status.OOB_RESTART_VALUE
    && s.getNumber() <= Status.OOB_RESERVED3_VALUE) {
  timeout = datanode.getOOBTimeout(s);
} else {
  timeout = normalAckTimeoutMs; // ordinary ack path
}
Defensive patterns

Strategy: validation

Validate before calling

boolean isOob = status.getNumber() >= Status.OOB_RESTART_VALUE
    && status.getNumber() <= Status.OOB_RESERVED3_VALUE;
if (isOob) {
  long timeout = datanode.getOOBTimeout(status);
} else {
  // ordinary status: use the normal ack timeout, never getOOBTimeout
}

Type guard

// Java predicate acting as a type guard over the Status enum range
static boolean isOobStatus(Status s) {
  return s != null
      && s.getNumber() >= Status.OOB_RESTART_VALUE
      && s.getNumber() <= Status.OOB_RESERVED3_VALUE;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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