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

  1. Look at the cause chained in the RuntimeException to find the real metadata store error.
  2. Verify store connectivity, authentication, and ACLs on the underreplication layout path.
  3. Restart the broker once the metadata store is healthy — layout creation is retried on initialization.
  4. 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

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


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