{"record":{"id":"fa17ff7142f55b74","repo":"apache/pulsar","slug":"etcd-metadata-store-backend-has-been-removed-in-pu","errorCode":null,"errorMessage":"Etcd metadata store backend has been removed in Pulsar 5.0 (PIP-462). Please use ZooKeeper (zk:) or Oxia (oxia:) as your metadata store.","messagePattern":"Etcd metadata store backend has been removed in Pulsar 5\\.0 \\(PIP-462\\)\\. Please use ZooKeeper \\(zk:\\) or Oxia \\(oxia:\\) as your metadata store\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/MetadataStoreFactoryImpl.java","lineNumber":93,"sourceCode":"        for (String className : Splitter.on(',').trimResults().omitEmptyStrings().split(factoryClasses)) {\n            try {\n                @SuppressWarnings(\"unchecked\")\n                Class<? extends MetadataStoreProvider> clazz =\n                        (Class<? extends MetadataStoreProvider>) Class.forName(className);\n                MetadataStoreProvider provider = clazz.getConstructor().newInstance();\n                String scheme = provider.urlScheme();\n                providers.put(scheme + \":\", provider);\n            } catch (Exception e) {\n                log.warn().attr(\"className\", className).exception(e)\n                        .log(\"Failed to load metadata store provider class\");\n            }\n        }\n        return providers;\n    }\n\n    private static MetadataStoreProvider findProvider(String metadataURL) {\n        if (metadataURL.startsWith(\"etcd:\")) {\n            throw new IllegalArgumentException(\n                    \"Etcd metadata store backend has been removed in Pulsar 5.0 (PIP-462). \"\n                            + \"Please use ZooKeeper (zk:) or Oxia (oxia:) as your metadata store.\");\n        }\n        Map<String, MetadataStoreProvider> providers = loadProviders();\n        for (Map.Entry<String, MetadataStoreProvider> entry : providers.entrySet()) {\n            if (metadataURL.startsWith(entry.getKey())) {\n                return entry.getValue();\n            }\n        }\n        return providers.get(ZK_SCHEME_IDENTIFIER);\n    }\n\n    /**\n     * Removes the identifier from the full metadata url.\n     *\n     * zk:my-zk:3000 -> my-zk:3000\n     * my-default-zk:3000 -> my-default-zk:3000\n     * @param metadataURL","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/MetadataStoreFactoryImpl.java#L75-L111","documentation":"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.","triggerScenarios":"Creating a metadata store with metadataURL beginning with \"etcd:\" via MetadataStoreFactory/MetadataStoreFactoryImpl after upgrading to Pulsar 5.0+.","commonSituations":"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.","solutions":["Migrate the metadata store data to ZooKeeper or Oxia (e.g., via the PIP-462 migration tooling) and change metadataUrl to \"zk:...\" or \"oxia://...\"","Remove etcd: entries from all configuration files (broker.conf, bookkeeper.conf, standalone.conf, client configs)","Pin to Pulsar 4.x only if etcd support is a hard requirement (not recommended)"],"exampleFix":"// before\nMetadataStore store = MetadataStoreFactory.create(\"etcd://etcd1:2379\", cfg);\n// after\nMetadataStore store = MetadataStoreFactory.create(\"oxia://oxia1:6648\", cfg);","handlingStrategy":"validation","validationCode":"// Java: pre-flight check for removed backends\nif (metadataURL.startsWith(\"etcd:\")) {\n    throw new IllegalArgumentException(\"etcd backend removed in Pulsar 5.0; migrate to zk: or oxia://\");\n}\n","typeGuard":"boolean isSupportedMetadataUrl(String url) {\n    return url.startsWith(\"zk:\") || url.startsWith(\"oxia:\")\n        || url.startsWith(\"rocksdb:\") || url.startsWith(\"memory:\");\n}\n","tryCatchPattern":"try {\n    MetadataStore store = MetadataStoreFactory.create(metadataURL, cfg);\n} catch (IllegalArgumentException e) {\n    // migrate config to zk: or oxia:// per PIP-462\n}\n","preventionTips":["Before upgrading to Pulsar 5.0, migrate off etcd and update metadataUrl in all configs","Grep config files and launch scripts for \"etcd:\" during upgrade planning","Standardize on zk: or oxia:// metadata URLs across environments"],"tags":["metadata-store","removed-feature","etcd","migration","configuration"],"backgroundTag":"metadata-backend-removed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}