{"record":{"id":"f0611bf6edc8cb65","repo":"apache/pulsar","slug":"is-not-an-instance-of-metadatastore","errorCode":null,"errorMessage":" is not an instance of MetadataStore","messagePattern":" is not an instance of MetadataStore","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/bookie/rackawareness/BookieRackAffinityMapping.java","lineNumber":78,"sourceCode":"public class BookieRackAffinityMapping extends AbstractDNSToSwitchMapping\n        implements RackChangeNotifier {\n\n    public static final String BOOKIE_INFO_ROOT_PATH = \"/bookies\";\n    public static final String METADATA_STORE_INSTANCE = \"METADATA_STORE_INSTANCE\";\n\n    private MetadataCache<BookiesRackConfiguration> bookieMappingCache = null;\n    private volatile ITopologyAwareEnsemblePlacementPolicy<BookieNode> rackawarePolicy = null;\n    private List<BookieId> bookieAddressListLastTime = new ArrayList<>();\n\n    private BookiesRackConfiguration racksWithHost = new BookiesRackConfiguration();\n    private Map<String, BookieInfo> bookieInfoMap = new HashMap<>();\n\n    static MetadataStore getMetadataStore(Configuration conf) throws MetadataException {\n        MetadataStore store;\n        Object storeProperty = conf.getProperty(METADATA_STORE_INSTANCE);\n        if (storeProperty != null) {\n            if (!(storeProperty instanceof MetadataStore)) {\n                throw new RuntimeException(METADATA_STORE_INSTANCE + \" is not an instance of MetadataStore\");\n            }\n            store = (MetadataStore) storeProperty;\n        } else {\n            String url;\n            String metadataServiceUri = ConfigurationStringUtil.castToString(conf.getProperty(\"metadataServiceUri\"));\n            if (StringUtils.isNotBlank(metadataServiceUri)) {\n                try {\n                    url = metadataServiceUri.replaceFirst(METADATA_STORE_SCHEME + \":\", \"\")\n                            .replace(\";\", \",\");\n                } catch (Exception e) {\n                    throw new MetadataException(Code.METADATA_SERVICE_ERROR, e);\n                }\n            } else {\n                String zkServers = ConfigurationStringUtil.castToString(conf.getProperty(\"zkServers\"));\n                if (StringUtils.isBlank(zkServers)) {\n                    String errorMsg = String.format(\"Neither %s configuration set in the BK client configuration nor \"\n                            + \"metadataServiceUri/zkServers set in bk server configuration\", METADATA_STORE_INSTANCE);\n                    throw new RuntimeException(errorMsg);","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/bookie/rackawareness/BookieRackAffinityMapping.java#L60-L96","documentation":"BookieRackAffinityMapping.getMetadataStore reads the METADATA_STORE_INSTANCE property from the BookKeeper configuration. If that property is set but holds an object that is not a MetadataStore (wrong type injected programmatically), a RuntimeException naming the property is thrown.","triggerScenarios":"A Configuration passed to setConf()/initialize() contains METADATA_STORE_INSTANCE bound to an object of a type other than MetadataStore — only possible via programmatic configuration, not string config files.","commonSituations":"Embedding BookKeeper/Pulsar in tests or custom code and passing a mock, a different store implementation, or a Supplier/wrapper object under that key; type changes across library versions.","solutions":["Set METADATA_STORE_INSTANCE to an actual org.apache.pulsar.metadata.api.MetadataStore instance","Or remove the property and supply metadataServiceUri / zkServers so the store is created from a URI","Check the injected object is not a mock/wrapper — use MetadataStoreExtended.create() to build it"],"exampleFix":"// before\nconf.setProperty(METADATA_STORE_INSTANCE, mockStoreBuilder); // wrong type\n// after\nMetadataStore store = MetadataStoreExtended.create(\"zk+sasl://zk1:2181/ledgers\", ...);\nconf.setProperty(METADATA_STORE_INSTANCE, store);","handlingStrategy":"type-guard","validationCode":"Object v = conf.getProperty(METADATA_STORE_INSTANCE);\nif (v != null && !(v instanceof MetadataStore)) {\n    throw new IllegalArgumentException(\"METADATA_STORE_INSTANCE must be a MetadataStore\");\n}","typeGuard":"static boolean isValidStore(Object o) {\n    return o == null || o instanceof MetadataStore;\n}","tryCatchPattern":"try {\n    mapping.setConf(conf);\n} catch (RuntimeException e) {\n    log.error(\"bad METADATA_STORE_INSTANCE\", e);\n}","preventionTips":["Only inject real MetadataStore instances programmatically","Prefer URI-based config (metadataServiceUri) over object injection","Update mocks/tests after MetadataStore API changes"],"tags":["configuration","metadata-store","type-mismatch"],"backgroundTag":"config-type-mismatch","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"}