quarkusio/quarkus · error · CacheException
An existing cached value type does not match the type return
Error message
An existing cached value type does not match the type returned by the value loading function
What it means
Thrown by CaffeineCacheImpl.cast when a value produced by the value loading function (or retrieved from the cache) cannot be cast to the generic type T expected by the caller of get(). The cache stores Object values, so mixing value types in one cache triggers a ClassCastException wrapped in a CacheException.
Source
Thrown at extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheImpl.java:344
"maximum-size configuration value");
}
}
// For testing purposes only.
public CaffeineCacheInfo getCacheInfo() {
return cacheInfo;
}
public long getSize() {
return cache.synchronous().estimatedSize();
}
@SuppressWarnings("unchecked")
private <T> T cast(Object value) {
try {
return (T) value;
} catch (ClassCastException e) {
throw new CacheException(
"An existing cached value type does not match the type returned by the value loading function", e);
}
}
@SuppressWarnings("unchecked")
private <V> Function<V, V> fromCacheValue() {
return (Function<V, V>) FROM_CACHE_VALUE;
}
private interface StatsRecorder {
void onValueAbsent();
<K> void doRecord(K key);
}
private static class NoopStatsRecorder implements StatsRecorder {View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the loading function's return type matches the cache's declared value type
- Use a separate cache name per value type
- Clear the cache to drop stale entries of the old type
Example fix
// before
Cache cache = cacheManager.getCache("shared");
String s = cache.get("k", id -> new User(id)); // loader returns User, caller wants String
// after
Cache userCache = cacheManager.getCache("userCache");
User u = userCache.get("k", id -> new User(id)); Defensive patterns
Strategy: type-guard
Validate before calling
// ensure loader output matches the cache's value type
V loaded = loader.apply(key);
if (!(loaded instanceof ExpectedType)) {
throw new IllegalArgumentException("loader returned wrong type");
} Type guard
boolean loaderReturnsExpectedType(Function<K, ?> loader, K key) {
return loader.apply(key) instanceof ExpectedType;
} Try / catch
try {
T value = cache.get(key, loader);
} catch (CacheException e) {
if (e.getCause() instanceof ClassCastException) {
cache.invalidate(key).await().indefinitely();
value = cache.get(key, loader);
} else { throw e; }
} Prevention
- Align the loading function's return type with the cache's generic type
- Use dedicated cache names per type
- Clear caches after type-changing refactors
When it happens
Trigger: Calling get(key, loadingFunction) where the loading function returns a different type than the entries already cached under that key, or where callers use different generic types for the same cache.
Common situations: A loader whose return type was changed; two application methods sharing a cache name but returning different types; dev-mode hot reload retaining old entries.
Related errors
- An existing cached value type does not match the requested t
- The write-based expiration policy can only be changed if the
- The access-based expiration policy can only be changed if th
- The maximum size can only be changed if the cache was constr
- Weigher class '<className>' must implement com.github.benman
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0071ba3fa311ab8f.
Report an issue: GitHub.