apache/pulsar · error · RuntimeException
RuntimeException
Error message
RuntimeException
What it means
checkLayout ensures the underreplication LAYOUT znode exists, creating it with put(..., expectedVersion=-1) when missing. If the store put fails with anything other than BadVersionException (i.e. it failed for a reason other than the node already existing), the cause is rethrown as an unchecked RuntimeException, signaling an unexpected metadata store failure.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerUnderreplicationManager.java:192
try {
lockData.setBookieId(DNS.getDefaultHost("default"));
} catch (UnknownHostException uhe) {
// if we cant get the address, ignore. it's optional
// in the data structure in any case
}
return lockData.toTextFormat().getBytes(UTF_8);
}
private void checkLayout() throws ReplicationException.CompatibilityException {
while (true) {
if (!store.exists(layoutPath).join()) {
LedgerRereplicationLayoutFormat layoutFormat = new LedgerRereplicationLayoutFormat();
layoutFormat.setType(LAYOUT).setVersion(LAYOUT_VERSION);
try {
store.put(layoutPath, layoutFormat.toTextFormat().getBytes(UTF_8), Optional.of(-1L)).get();
} catch (ExecutionException | InterruptedException e) {
if (!(e.getCause() instanceof MetadataStoreException.BadVersionException)) {
throw new RuntimeException(e);
}
}
} else {
byte[] layoutData = store.get(layoutPath).join().get().getValue();
LedgerRereplicationLayoutFormat layout = new LedgerRereplicationLayoutFormat();
try {
layout.parseFromTextFormat(layoutData);
if (!layout.getType().equals(LAYOUT)
|| layout.getVersion() != LAYOUT_VERSION) {
throw new ReplicationException.CompatibilityException(
"Incompatible layout found (" + LAYOUT + ":" + LAYOUT_VERSION + ")");
}
} catch (RuntimeException pe) {
throw new ReplicationException.CompatibilityException(
"Invalid data found", pe);
}View on GitHub (pinned to 820761864e)
Solutions
- Look at the cause chained in the RuntimeException to find the real metadata store error.
- Verify store connectivity, authentication, and ACLs on the underreplication layout path.
- Restart the broker once the metadata store is healthy — layout creation is retried on initialization.
- Ensure all brokers use the same ledgers root so the layout node is created consistently.
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check write access to the layout path store.exists(layoutPath).get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
Try / catch
try {
new PulsarLedgerUnderreplicationManager(store, basePath, ...);
} catch (RuntimeException e) {
log.error("Layout creation failed: {}", e.getCause(), e); // inspect MetadataStoreException cause
} Prevention
- Ensure the broker's metadata service URL and credentials allow writes on the underreplication path.
- Check store connectivity before broker startup; this runs during initialization.
- Grant ACLs on the underreplication base path for the broker identity.
When it happens
Trigger: Initializing PulsarLedgerUnderreplicationManager while the metadata store errors on the conditional put of the layout node — store unreachable, session expired, permission denied, or non-sequential unexpected errors; BadVersionException (node already exists) is tolerated and NOT thrown.
Common situations: Metadata store outage during broker startup; ACL/permission problems on the underreplication layout path; interrupted store session; misconfigured metadata service URL.
Related errors
- IOException
- Incompatible layout found (LAYOUT:1)
- Invalid data found
- Metadata store address argument is required (--metadata-stor
- Failed to validate global cluster configuration
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/1d47afebe04807ab.
Report an issue: GitHub.