apache/pulsar · error · UnsupportedOperationException
Metadata cache implementation ${className} not supported by
Error message
Metadata cache implementation ${className} not supported by FaultInjectionMetadataStore What it means
FaultInjectionMetadataStore is a test wrapper that must inject itself into every MetadataCache it hands out, replacing the cache's internal `store` field. It can only do this for MetadataCacheImpl instances; for any other MetadataCache implementation it throws UnsupportedOperationException naming the class, after reflectively overwriting the field via FieldUtils.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/FaultInjectionMetadataStore.java:193
@Override
public <T> MetadataCache<T> getMetadataCache(TypeReference<T> typeRef, MetadataCacheConfig<?> cacheConfig) {
return injectMetadataStoreInMetadataCache(store.getMetadataCache(typeRef, cacheConfig));
}
@SuppressWarnings("deprecation")
@Override
public <T> MetadataCache<T> getMetadataCache(String cacheName, MetadataSerde<T> serde,
MetadataCacheConfig<?> cacheConfig) {
return injectMetadataStoreInMetadataCache(store.getMetadataCache(serde, cacheConfig));
}
@SneakyThrows
private <T> MetadataCache<T> injectMetadataStoreInMetadataCache(MetadataCache<T> metadataCache) {
if (metadataCache instanceof MetadataCacheImpl) {
FieldUtils.writeField(metadataCache, "store", this, true);
} else {
throw new UnsupportedOperationException("Metadata cache implementation "
+ metadataCache.getClass().getName() + " not supported by FaultInjectionMetadataStore");
}
return metadataCache;
}
@Override
public void registerSessionListener(Consumer<SessionEvent> listener) {
store.registerSessionListener(listener);
sessionListeners.add(listener);
}
@Override
public CompletableFuture<Void> handleMetadataEvent(MetadataEvent event) {
return store.handleMetadataEvent(event);
}
@Override
public void close() throws Exception {View on GitHub (pinned to 820761864e)
Solutions
- Use a metadata store whose getMetadataCache returns standard MetadataCacheImpl instances (e.g., the built-in ZK/Oxia/RocksDB stores)
- Update the custom MetadataCache implementation to extend MetadataCacheImpl
- Only wrap stores with FaultInjectionMetadataStore that are known-compatible in tests
Example fix
// before FaultInjectionMetadataStore faultStore = new FaultInjectionMetadataStore(customStore); // custom cache // after FaultInjectionMetadataStore faultStore = new FaultInjectionMetadataStore(new OxiaMetadataStore(cfg));
Defensive patterns
Strategy: type-guard
Validate before calling
// Java: only wrap stores whose caches are standard impls
MetadataCache<?> cache = store.getMetadataCache(String.class);
if (!(cache instanceof MetadataCacheImpl)) {
throw new IllegalStateException("Store not compatible with FaultInjectionMetadataStore");
}
Type guard
static boolean supportsFaultInjection(MetadataCache<?> cache) {
return cache instanceof MetadataCacheImpl;
}
Try / catch
try {
MetadataCache<T> c = faultStore.getMetadataCache(String.class);
} catch (UnsupportedOperationException e) {
// store returns a non-standard cache; switch to a built-in store in tests
}
Prevention
- Use built-in metadata stores (zk:, oxia:, rocksdb:, memory:) in fault-injection tests
- Keep custom MetadataCache implementations extending MetadataCacheImpl
- Check compatibility before wrapping a store with FaultInjectionMetadataStore
When it happens
Trigger: Calling FaultInjectionMetadataStore.getMetadataCache() when the underlying store returns a non-MetadataCacheImpl cache implementation — typically a custom or third-party MetadataCache subclass.
Common situations: Using FaultInjectionMetadataStore in tests with a custom metadata store/cache implementation that does not extend MetadataCacheImpl.
Related errors
- Failed to load an authorization provider.
- Failed to instantiate ${className}
- Exception caused while converting configuration: ${message}
- Failed to compute configuration overrides
- Cannot disable validation of default values
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/375ae575c3029823.
Report an issue: GitHub.