apache/pulsar · error · ReplicationException.UnavailableException

Error contacting zookeeper

Error message

Error contacting zookeeper

What it means

Thrown by isLedgerReplicationEnabled() when the blocking exists() check on the replication-disable node in the metadata store fails (ExecutionException) or times out (TimeoutException). The method answers whether auto re-replication is currently enabled by testing the absence of the node; without a working store it cannot answer, so it throws ReplicationException.UnavailableException with this legacy message.

Source

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

            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(
                    "Interrupted while contacting zookeeper", ie);
        }
    }

    @Override
    public void notifyLedgerReplicationEnabled(final BookkeeperInternalCallbacks.GenericCallback<Void> cb)
            throws ReplicationException.UnavailableException {
        log.debug("notifyLedgerReplicationEnabled()");
        synchronized (replicationEnabledCallbacks) {
            replicationEnabledCallbacks.add(cb);
        }
        try {
            if (!store.exists(replicationDisablePath)
                    .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS)) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Verify metadata store health before querying replication state.
  2. Catch this exception and treat state as unknown rather than enabled/disabled in monitoring logic.
  3. Check the wrapped cause for the root store error (connection loss, session expired).
  4. Retry with backoff; exists() is read-only and safe to repeat.

Example fix

// before
boolean enabled = urManager.isLedgerReplicationEnabled(); // throws during ZK outage
// after
boolean enabled;
try {
    enabled = urManager.isLedgerReplicationEnabled();
} catch (ReplicationException.UnavailableException e) {
    enabled = true; // fail open or report unknown state
    log.warn("Cannot determine replication state", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// probe store liveness before asking replication state
store.exists("/admin/probe").get(5, TimeUnit.SECONDS);

Type guard

Optional<Boolean> safeReplicationEnabled(LedgerUnderreplicationManager m) {
    try { return Optional.of(m.isLedgerReplicationEnabled()); }
    catch (ReplicationException.UnavailableException e) { return Optional.empty(); }
}

Try / catch

try {
    boolean enabled = urManager.isLedgerReplicationEnabled();
} catch (ReplicationException.UnavailableException e) {
    // state unknown: do not assume enabled; mark metric 'replication_state_unknown'
}

Prevention

When it happens

Trigger: Calling isLedgerReplicationEnabled() while the metadata store is down, session expired, or the exists() call exceeds BLOCKING_CALL_TIMEOUT.

Common situations: Health/status checks during a ZooKeeper outage; monitoring scripts polling replication state while the metadata service is saturated or unreachable.

Related errors


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