apache/pulsar · error · IllegalArgumentException

Etcd metadata store backend has been removed in Pulsar 5.0 (

Error message

Etcd metadata store backend has been removed in Pulsar 5.0 (PIP-462). Please use ZooKeeper (zk:) or Oxia (oxia:) as your metadata store.

What it means

PIP-462 removed the etcd metadata store backend in Pulsar 5.0. MetadataStoreFactoryImpl.findProvider() hard-fails any URL starting with "etcd:" with an IllegalArgumentException explaining the removal and pointing users to ZooKeeper (zk:) or Oxia (oxia:) instead — the check runs before provider lookup so etcd can never be silently re-registered.

Source

Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/MetadataStoreFactoryImpl.java:93

        for (String className : Splitter.on(',').trimResults().omitEmptyStrings().split(factoryClasses)) {
            try {
                @SuppressWarnings("unchecked")
                Class<? extends MetadataStoreProvider> clazz =
                        (Class<? extends MetadataStoreProvider>) Class.forName(className);
                MetadataStoreProvider provider = clazz.getConstructor().newInstance();
                String scheme = provider.urlScheme();
                providers.put(scheme + ":", provider);
            } catch (Exception e) {
                log.warn().attr("className", className).exception(e)
                        .log("Failed to load metadata store provider class");
            }
        }
        return providers;
    }

    private static MetadataStoreProvider findProvider(String metadataURL) {
        if (metadataURL.startsWith("etcd:")) {
            throw new IllegalArgumentException(
                    "Etcd metadata store backend has been removed in Pulsar 5.0 (PIP-462). "
                            + "Please use ZooKeeper (zk:) or Oxia (oxia:) as your metadata store.");
        }
        Map<String, MetadataStoreProvider> providers = loadProviders();
        for (Map.Entry<String, MetadataStoreProvider> entry : providers.entrySet()) {
            if (metadataURL.startsWith(entry.getKey())) {
                return entry.getValue();
            }
        }
        return providers.get(ZK_SCHEME_IDENTIFIER);
    }

    /**
     * Removes the identifier from the full metadata url.
     *
     * zk:my-zk:3000 -> my-zk:3000
     * my-default-zk:3000 -> my-default-zk:3000
     * @param metadataURL

View on GitHub (pinned to 820761864e)

Solutions

  1. Migrate the metadata store data to ZooKeeper or Oxia (e.g., via the PIP-462 migration tooling) and change metadataUrl to "zk:..." or "oxia://..."
  2. Remove etcd: entries from all configuration files (broker.conf, bookkeeper.conf, standalone.conf, client configs)
  3. Pin to Pulsar 4.x only if etcd support is a hard requirement (not recommended)

Example fix

// before
MetadataStore store = MetadataStoreFactory.create("etcd://etcd1:2379", cfg);
// after
MetadataStore store = MetadataStoreFactory.create("oxia://oxia1:6648", cfg);
Defensive patterns

Strategy: validation

Validate before calling

// Java: pre-flight check for removed backends
if (metadataURL.startsWith("etcd:")) {
    throw new IllegalArgumentException("etcd backend removed in Pulsar 5.0; migrate to zk: or oxia://");
}

Type guard

boolean isSupportedMetadataUrl(String url) {
    return url.startsWith("zk:") || url.startsWith("oxia:")
        || url.startsWith("rocksdb:") || url.startsWith("memory:");
}

Try / catch

try {
    MetadataStore store = MetadataStoreFactory.create(metadataURL, cfg);
} catch (IllegalArgumentException e) {
    // migrate config to zk: or oxia:// per PIP-462
}

Prevention

When it happens

Trigger: Creating a metadata store with metadataURL beginning with "etcd:" via MetadataStoreFactory/MetadataStoreFactoryImpl after upgrading to Pulsar 5.0+.

Common situations: Upgrading a cluster from Pulsar 4.x (where etcd was supported) to 5.0 without changing metadataUrl configuration; leftover etcd:// URLs in broker/bookie/standalone config or test fixtures.

Related errors


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