apache/hadoop · error · IOException

Interrupted waiting for discardSegments() response

Error message

Interrupted waiting for discardSegments() response

What it means

discardSegments(startTxId) — the QJM call that drops every edit segment from startTxId onward, used by the NameNode rollback procedure on shared edits — was interrupted while waiting for all JournalNodes to respond. InterruptedException is wrapped in this IOException.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/client/QuorumJournalManager.java:782

    } catch (InterruptedException e) {
      throw new IOException("Interrupted waiting for doFinalize() response");
    } catch (TimeoutException e) {
      throw new IOException("Timed out waiting for doFinalize() response");
    }
  }
  
  @Override
  public void discardSegments(long startTxId) throws IOException {
    QuorumCall<AsyncLogger, Void> call = loggers.discardSegments(startTxId);
    try {
      call.waitFor(loggers.size(), loggers.size(), 0,
          timeoutMs, "discardSegments");
      if (call.countExceptions() > 0) {
        call.rethrowException(
            "Could not perform discardSegments of one or more JournalNodes");
      }
    } catch (InterruptedException e) {
      throw new IOException(
          "Interrupted waiting for discardSegments() response");
    } catch (TimeoutException e) {
      throw new IOException(
          "Timed out waiting for discardSegments() response");
    }
  }
  
  @Override
  public long getJournalCTime() throws IOException {
    QuorumCall<AsyncLogger, Long> call = loggers.getJournalCTime();
    try {
      call.waitFor(loggers.size(), loggers.size(), 0,
          timeoutMs, "getJournalCTime");
      
      if (call.countExceptions() > 0) {
        call.rethrowException("Could not journal CTime for one "
            + "more JournalNodes");
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Determine what interrupted the thread (shutdown, failover, operator) from surrounding logs and eliminate that trigger.
  2. Audit each JN's current dir for which segments were actually deleted; reconcile by syncing from a healthy JN's directory.
  3. Re-run the rollback/discard procedure once all JNs are consistent and no interrupt source remains.
  4. If calling this API directly, structure cancellation to occur between quorum calls, never during one.
Defensive patterns

Strategy: try-catch

Type guard

static boolean isDiscardInterrupted(IOException ioe) {
  return ioe.getMessage() != null
      && ioe.getMessage().contains("Interrupted waiting for discardSegments");
}

Try / catch

try {
  qjm.discardSegments(startTxId);
} catch (IOException ioe) {
  if (isDiscardInterrupted(ioe)) {
    Thread.currentThread().interrupt();
    auditWhichJnsDiscarded(); // deletion may be partial across the quorum
    return;
  }
  throw ioe;
}

Prevention

When it happens

Trigger: A thread interrupt lands while discardSegments is waiting on the quorum call: NN shutdown or HA transition during rollback, operator cancellation, or tooling interrupting the worker thread mid-procedure.

Common situations: Operator aborts 'hdfs namenode -rollback' while the NN is discarding newer segments; automated scripts interrupt on outer timeouts. Partial completion is possible: some JNs may have deleted segments while others have not, leaving the quorum inconsistent.

Related errors


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