apache/pulsar · error · ReplicationException.UnavailableException
Exception while resuming auto ledger re-replication
Error message
Exception while resuming auto ledger re-replication
What it means
Thrown by PulsarLedgerUnderreplicationManager.enableLedgerReplication() when the blocking metadata-store delete of the replication-disable node (replicationDisablePath) fails or times out. BookKeeper's underreplication manager uses this node to disable auto ledger re-replication; enabling means deleting it. If the underlying MetadataStore operation completes exceptionally (ExecutionException) or does not finish within BLOCKING_CALL_TIMEOUT (TimeoutException), the manager wraps it in ReplicationException.UnavailableException.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java:741
"Exception while stopping auto ledger re-replication", ee);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new ReplicationException.UnavailableException(
"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(View on GitHub (pinned to 820761864e)
Solutions
- Check metadata-store connectivity and health (zookeeper quorum, network, TLS) from the broker.
- Retry enableLedgerReplication() after the store recovers; the delete is idempotent.
- Inspect the cause (getCause()) for ExecutionException to find the exact store failure (session expired, no quorum, etc.).
- Increase timeout pressure margin (e.g. fix ZooKeeper latency) if timeouts recur under load.
Example fix
// before
auditor.enableLedgerReplication(); // throws on transient ZK blip
// after
try {
auditor.enableLedgerReplication();
} catch (ReplicationException.UnavailableException e) {
log.warn("Metadata store unavailable, will retry", e);
// schedule retry after store health check
} Defensive patterns
Strategy: retry
Validate before calling
// verify store reachable before enabling
if (!store.exists(replicationDisablePath).get(5, TimeUnit.SECONDS) != null) {
throw new IllegalStateException("Metadata store unreachable");
} Type guard
boolean isMetadataStoreHealthy(MetadataStore store) {
try {
store.exists("/health-check-probe").get(5, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
return false;
}
} Try / catch
try {
urManager.enableLedgerReplication();
} catch (ReplicationException.UnavailableException e) {
Throwable cause = e.getCause();
if (cause instanceof TimeoutException) {
// retry with backoff
} else {
// alert on store connectivity
}
} Prevention
- Monitor metadata store health before issuing admin replication operations.
- Retry idempotent enable/delete operations with exponential backoff.
- Alert on ZooKeeper session expiry and quorum loss so operations are not attempted during outages.
When it happens
Trigger: Calling enableLedgerReplication() (or its Admin API equivalent) when the metadata store (ZooKeeper/etcd) is down, unreachable, session expired, slow, or the delete exceeds BLOCKING_CALL_TIMEOUT.
Common situations: ZooKeeper quorum lost or overloaded during a cluster incident; network partition between broker and metadata store; long GC pauses on ZooKeeper making the delete exceed the blocking timeout; calling the admin API while the metadata service is restarting.
Related errors
- Failed to get children of ${path}
- Failed to check exist ${POLICIES_READONLY_FLAG_PATH}
- Error preloading next range
- Error when get child nodes from zk
- Error contacting with metadata store
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/8ae599d09c652a25.
Report an issue: GitHub.