apache/pulsar · warning · ReplicationException.UnavailableException
Interrupted while contacting metadata store
Error message
Interrupted while contacting metadata store
What it means
Thrown by markLedgerReplicated when the thread waiting on the blocking metadata-store future is interrupted; the InterruptedException cause carries the interruption. The method re-asserts the interrupt flag (Thread.currentThread().interrupt()) before wrapping, so interruption is not swallowed. This is ReplicationException.UnavailableException, i.e. the operation did not complete because the caller stopped waiting.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java:485
}
}
}
} catch (ExecutionException ee) {
if (ee.getCause() instanceof MetadataStoreException.NotFoundException) {
// this is ok
} else if (ee.getCause() instanceof MetadataStoreException.BadVersionException) {
// if this is the case, some has marked the ledger
// for rereplication again. Leave the underreplicated
// znode in place, so the ledger is checked.
} else {
log.error().exception(ee).log("Error deleting underreplicated ledger node");
throw new ReplicationException.UnavailableException("Error contacting metadata store", ee);
}
} catch (TimeoutException ex) {
throw new ReplicationException.UnavailableException("Error contacting metadata store", ex);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new ReplicationException.UnavailableException("Interrupted while contacting metadata store", ie);
} finally {
releaseUnderreplicatedLedger(ledgerId);
}
}
/**
* Get a list of all the underreplicated ledgers which have been
* marked for rereplication, filtered by the predicate on the replicas list.
*
* <p>Replicas list of an underreplicated ledger is the list of the bookies which are part of
* the ensemble of this ledger and are currently unavailable/down.
*
* @param predicate filter to use while listing under replicated ledgers. 'null' if filtering is not required.
* @return an iterator which returns underreplicated ledgers.
*/
@Override
public Iterator<UnderreplicatedLedger> listLedgersToRereplicate(final Predicate<List<String>> predicate) {
final Queue<String> queue = new LinkedList<>();View on GitHub (pinned to 820761864e)
Solutions
- Check whether the broker/auditor was shutting down at the time; if so this is expected and needs no fix.
- Avoid interrupting the thread running markLedgerReplicated; let in-flight rereplication finish before calling shutdownNow().
- Re-check the interrupt flag in your caller (it is preserved) and abort gracefully rather than retrying immediately.
- If interruptions come from your own executor, use awaitTermination with a generous timeout after shutdown() before shutdownNow().
Example fix
// before: swallowing the exception and losing the interrupt flag
catch (ReplicationException.UnavailableException e) { /* ignore */ }
// after: detect interruption and stop the loop
} catch (ReplicationException.UnavailableException e) {
if (Thread.currentThread().isInterrupted()) {
log.info("Interrupted during markLedgerReplicated, stopping rereplication loop");
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Java: skip the call when the thread is already interrupted
if (Thread.currentThread().isInterrupted()) {
return; // don't start blocking metadata-store work while interrupted
} Try / catch
try {
manager.markLedgerReplicated(ledgerId);
} catch (ReplicationException.UnavailableException e) {
if (Thread.currentThread().isInterrupted()) {
Thread.currentThread().interrupt(); // preserve flag, stop work
return;
}
throw e; // genuine store unavailability
} Prevention
- Gracefully stop rereplication tasks before executor.shutdownNow()
- Use awaitTermination with a sufficient timeout after shutdown()
- Check Thread.interrupted() before entering blocking metadata-store calls
- Never swallow InterruptedException — re-set the flag like the library does
When it happens
Trigger: Calling markLedgerReplicated(ledgerId) while the calling thread (typically the auditor's scheduled executor or a shutdown hook) is interrupted, e.g. during broker shutdown, executor.shutdownNow(), or a task cancelled while blocked in .get(BLOCKING_CALL_TIMEOUT) on store.delete/store.get.
Common situations: Broker/auditor shutdown racing with ledger replication completion; BookKeeper client closing its callback executors; tests cancelling futures; thread pools being torn down while rereplication work is in flight.
Related errors
- Interrupted while reading ledgers at path ${path}
- IOException
- Interrupted while connecting metadata store
- Interrupted initializing OAuth2 IdP TLS factory
- Interrupted at fetching schema info for <SchemaUtils.getStri
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/93ee5aba79d5f16e.
Report an issue: GitHub.