redis/jedis · error · JedisCacheException

Failed to insantiate custom cache type!

Error message

Failed to insantiate custom cache type!

What it means

instantiateCustomCache reflectively constructs the configured custom Cache class via a (int maxSize, EvictionPolicy) constructor; any reflective failure — InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException (the constructor itself threw), or SecurityException — is wrapped in JedisCacheException('Failed to insantiate custom cache type!'). Check the wrapped cause for the real reason.

Solutions

  1. Inspect e.getCause() in the message/stacktrace to find the constructor's own exception and fix it.
  2. Ensure the custom cache class is concrete, public, and has a public (int maxSize, EvictionPolicy evictionPolicy) constructor (or the 3-arg variant with Cacheable).
  3. Validate maxSize and eviction policy values before building CacheConfig (e.g. maxSize > 0).
  4. Check the constructor body for throw statements that could fire for your config values.

Example fix

// before
class MyCache extends AbstractCache {
  private MyCache(int maxSize, EvictionPolicy policy) { ... } // non-public -> IllegalAccessException
}
// after
class MyCache extends AbstractCache {
  public MyCache(int maxSize, EvictionPolicy policy) {
    if (maxSize <= 0) throw new IllegalArgumentException("maxSize must be > 0");
    ...
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

Class<? extends Cache> type = config.getCacheClass();
if (type != null) {
  if (Modifier.isAbstract(type.getModifiers()) || type.isInterface())
    throw new IllegalArgumentException(type + " must be a concrete class");
  boolean hasCtor = Arrays.stream(type.getConstructors())
      .anyMatch(c -> Arrays.equals(c.getParameterTypes(), new Class[]{int.class, EvictionPolicy.class}));
  if (!hasCtor) throw new IllegalArgumentException(type + " lacks public (int, EvictionPolicy) constructor");
}

Try / catch

try {
  Cache cache = CacheFactory.getCache(config);
} catch (JedisCacheException e) {
  if (e.getMessage().contains("insantiate custom cache")) {
    Throwable cause = e.getCause(); // InstantiationException/InvocationTargetException etc.
    log.error("custom cache construction failed", cause);
  } else throw e;
}

Prevention

When it happens

Trigger: config.setCacheClass(X.class) where X is abstract or an interface (InstantiationException); the (int, EvictionPolicy) constructor throws internally (InvocationTargetException); the constructor rejects the maxSize/eviction arguments (IllegalArgumentException); a SecurityManager blocks reflection; the class's constructor is not accessible.

Common situations: Custom cache implementations with constructor-side validation that throws on the given maxSize (e.g. maxSize <= 0); pointing cacheClass at a Cache interface or abstract base class; container/environments with strict security policies limiting reflection.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/dd689e82c0c13bd2. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/csc/CacheFactory.java:33

            }
            return new DefaultCache(config.getMaxSize(), config.getCacheable(), getEvictionPolicy(config));
        }
        return instantiateCustomCache(config);
    }

    private static Cache instantiateCustomCache(CacheConfig config) {
        try {
            if (config.getCacheable() != null) {
                Constructor ctorWithCacheable = findConstructorWithCacheable(config.getCacheClass());
                if (ctorWithCacheable != null) {
                    return (Cache) ctorWithCacheable.newInstance(config.getMaxSize(), getEvictionPolicy(config), config.getCacheable());
                }
            }
            Constructor ctor = getConstructor(config.getCacheClass());
            return (Cache) ctor.newInstance(config.getMaxSize(), getEvictionPolicy(config));
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
                | SecurityException e) {
            throw new JedisCacheException("Failed to insantiate custom cache type!", e);
        }
    }

    private static Constructor findConstructorWithCacheable(Class customCacheType) {
        return Arrays.stream(customCacheType.getConstructors())
                .filter(ctor -> Arrays.equals(ctor.getParameterTypes(), new Class[] { int.class, EvictionPolicy.class, Cacheable.class }))
                .findFirst().orElse(null);
    }

    private static Constructor getConstructor(Class customCacheType) {
        try {
            return customCacheType.getConstructor(int.class, EvictionPolicy.class);
        } catch (NoSuchMethodException e) {
            String className = customCacheType.getName();
            throw new JedisCacheException(String.format(
                "Failed to find compatible constructor for custom cache type!  Provide one of these;"
                        // give hints about the compatible constructors
                        + "\n - %s(int maxSize, EvictionPolicy evictionPolicy)\n - %s(int maxSize, EvictionPolicy evictionPolicy, Cacheable cacheable)",

View on GitHub (pinned to 6dac31d4c2)