apache/pulsar · warning · ReplicationException.UnavailableException

Interrupted while resuming auto ledger re-replication

Error message

Interrupted while resuming auto ledger re-replication

What it means

Thrown by enableLedgerReplication() when the thread waiting on the metadata-store delete is interrupted before BLOCKING_CALL_TIMEOUT elapses. The method restores the interrupt flag (Thread.currentThread().interrupt()) and wraps the InterruptedException in ReplicationException.UnavailableException so callers of the BookKeeper underreplication API see a uniform checked type.

Source

Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java:745

                    "Interrupted while stopping auto ledger re-replication", ie);
        }
    }

    @Override
    public void enableLedgerReplication()
            throws ReplicationException.UnavailableException {
        log.debug("enableLedgerReplication()");
        try {
            store.delete(replicationDisablePath, Optional.empty())
                    .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);
            log.info("Resuming automatic ledger re-replication");
        } catch (ExecutionException | TimeoutException ee) {
            log.error().exception(ee).log("Exception while resuming ledger replication");
            throw new ReplicationException.UnavailableException(
                    "Exception while resuming auto ledger re-replication", ee);
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
            throw new ReplicationException.UnavailableException(
                    "Interrupted while resuming auto ledger re-replication", ie);
        }
    }

    @Override
    public boolean isLedgerReplicationEnabled()
            throws ReplicationException.UnavailableException {
        log.debug("isLedgerReplicationEnabled()");
        try {
            return !store.exists(replicationDisablePath)
                    .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);
        } catch (ExecutionException | TimeoutException ee) {
            log.error().exception(ee).log("Error while checking the state of ledger re-replication");
            throw new ReplicationException.UnavailableException(
                    "Error contacting zookeeper", ee);
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
            throw new ReplicationException.UnavailableException(

View on GitHub (pinned to 820761864e)

Solutions

  1. Re-check who interrupted the thread; on shutdown, abandon the operation and let it be re-run after restart.
  2. Preserve interrupt status in your own code (the manager already restores it) and avoid swallowing it.
  3. Retry the enable operation from a healthy, non-shutting-down thread if the interruption was unintended.

Example fix

// before
new Thread(() -> auditor.enableLedgerReplication()).start(); // interrupted on shutdown
// after
executor.submit(() -> {
    try {
        auditor.enableLedgerReplication();
    } catch (ReplicationException.UnavailableException e) {
        if (Thread.currentThread().isInterrupted()) {
            log.info("Enable replication cancelled by shutdown");
        }
    }
});
Defensive patterns

Strategy: try-catch

Validate before calling

if (Thread.currentThread().isInterrupted()) {
    throw new CancellationException("Thread already interrupted; skip enableLedgerReplication");
}

Type guard

boolean wasInterrupted(ReplicationException.UnavailableException e) {
    return e.getCause() instanceof InterruptedException
        || Thread.currentThread().isInterrupted();
}

Try / catch

try {
    urManager.enableLedgerReplication();
} catch (ReplicationException.UnavailableException e) {
    if (Thread.currentThread().isInterrupted()) {
        // intentional shutdown: abort quietly
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: The calling thread is interrupted (executor shutdown, broker shutdown, cancellation) while blocked in store.delete(...).get(timeout) inside enableLedgerReplication().

Common situations: Graceful broker shutdown cancels worker threads; an executor is shut down while an admin operation is in flight; a watchdog thread interrupts a stuck admin call.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/c65252159e0dde10. Report an issue: GitHub.