quarkusio/quarkus · error · CacheException
An existing cached value type does not match the requested t
Error message
An existing cached value type does not match the requested type
What it means
Thrown by CaffeineCacheImpl when a value already stored in the cache cannot be cast to the generic type V requested by the caller via the Cache API (the cache stores values as Object). This happens when the same cache name is used with different value types, e.g. after changing a method's return type or calling put() with a mismatched type. The ClassCastException is wrapped in a CacheException to give a clearer message.
Source
Thrown at extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheImpl.java:192
public <V> CompletableFuture<V> getIfPresent(Object key) {
Objects.requireNonNull(key, NULL_KEYS_NOT_SUPPORTED_MSG);
CompletableFuture<Object> existingCacheValue = cache.getIfPresent(key);
if (existingCacheValue == null) {
return null;
} else {
LOGGER.tracef("Key [%s] found in cache [%s]", key, cacheInfo.name);
// cast, but still throw the CacheException in case it fails
return unwrapCacheValueOrThrowable(existingCacheValue)
.thenApply(new Function<>() {
@SuppressWarnings("unchecked")
@Override
public V apply(Object value) {
try {
return (V) value;
} catch (ClassCastException e) {
throw new CacheException("An existing cached value type does not match the requested type", e);
}
}
});
}
}
/**
* Returns a {@link CompletableFuture} holding the cache value identified by {@code key}, obtaining that value from
* {@code valueLoader} if necessary. The value computation is done synchronously on the calling thread and the
* {@link CompletableFuture} is immediately completed before being returned.
*
* @param key cache key
* @param valueLoader function used to compute the cache value if {@code key} is not already associated with a value
* @return a {@link CompletableFuture} holding the cache value
* @throws CacheException if an exception is thrown during the cache value computation
*/
private <K, V> CompletableFuture<Object> getFromCaffeine(K key, Function<K, V> valueLoader) {View on GitHub (pinned to e1c734241f)
Solutions
- Use a distinct @CacheName/cache name for each value type
- Clear/invalidate the cache (or restart the app) so stale entries of the old type are removed
- Ensure the cached method's return type and all callers agree on one type
Example fix
// before
@CacheName("myCache")
public String getName(long id) { ... }
public User getUser(long id) { ... } // same cache, different type
// after
@CacheName("nameCache")
public String getName(long id) { ... }
@CacheName("userCache")
public User getUser(long id) { ... } Defensive patterns
Strategy: type-guard
Validate before calling
// store one type per cache name and verify before reads
Object existing = cache.get(key, k -> null);
if (existing != null && !(existing instanceof ExpectedType)) {
cache.invalidate(key).await().indefinitely();
} Type guard
boolean isExpectedType(Object value) {
return value instanceof ExpectedType;
} Try / catch
try {
V 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
- One cache name per value type
- Invalidate stale entries after changing a cached method's return type
- Restart or clear caches after dev-mode hot reloads that change types
When it happens
Trigger: Calling get/getAsync/put on a Caffeine-backed cache whose existing entries were stored under a different value type; the unchecked cast (V) value throws ClassCastException.
Common situations: Reusing a cache name for two methods with different return types; changing a cached method's return type while old entries persist; deserialization/classloader changes across hot redeployment in dev mode.
Related errors
- An existing cached value type does not match the type return
- 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/43e184f07f7780ad.
Report an issue: GitHub.