redis/jedis · error · JedisCacheException

Failed to find compatible constructor for custom cache…

Error message

Failed to find compatible constructor for custom cache type!  Provide one of these;
 - ${className}(int maxSize, EvictionPolicy evictionPolicy)
 - ${className}(int maxSize, EvictionPolicy evictionPolicy, Cacheable cacheable)

What it means

getConstructor looks for a public constructor matching (int, EvictionPolicy) on the configured custom cache class; if absent, it throws JedisCacheException listing the two accepted constructor signatures — with or without a trailing Cacheable parameter. This tells the developer their custom Cache class does not expose a constructor shape CacheFactory can invoke.

Solutions

  1. Add a public constructor X(int maxSize, EvictionPolicy evictionPolicy) to your custom cache class.
  2. Alternatively add X(int maxSize, EvictionPolicy evictionPolicy, Cacheable cacheable) so the cacheable-aware path can be used.
  3. If you cannot change the constructor, adapt with a thin subclass exposing the required (int, EvictionPolicy) constructor.
  4. Verify the class is public and the constructor is public (non-public constructors are invisible to getConstructor).

Example fix

// before
public class MyCache implements Cache {
  public MyCache() { ... } // no matching constructor
}
// after
public class MyCache implements Cache {
  public MyCache(int maxSize, EvictionPolicy evictionPolicy) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

static void requireCompatibleCacheCtor(Class<? extends Cache> type) {
  boolean ok = Arrays.stream(type.getConstructors()).anyMatch(c ->
      Arrays.equals(c.getParameterTypes(), new Class[]{int.class, EvictionPolicy.class}) ||
      Arrays.equals(c.getParameterTypes(), new Class[]{int.class, EvictionPolicy.class, Cacheable.class}));
  if (!ok) throw new IllegalArgumentException(type.getName() +
      " must expose public (int, EvictionPolicy) or (int, EvictionPolicy, Cacheable) constructor");
}

Try / catch

try {
  Cache cache = CacheFactory.getCache(config);
} catch (JedisCacheException e) {
  if (e.getMessage().contains("Failed to find compatible constructor")) {
    // add or expose the required constructor in the custom cache class
  } else throw e;
}

Prevention

When it happens

Trigger: config.setCacheClass(X.class) where X has no public constructor of shape (int maxSize, EvictionPolicy) or (int maxSize, EvictionPolicy, Cacheable) — e.g. only a no-arg constructor, only builders, or the 2-arg constructor is private/protected.

Common situations: Implementing a custom cache with dependency injection (no matching constructor); wrapping a third-party cache (e.g. Caffeine) whose constructors have different parameters; forgetting that the (int, EvictionPolicy, Cacheable) hint only works if findConstructorWithCacheable's path applies.

Related errors


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

Appendix: source

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

            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)",
                className, className), e);
        }
    }

    private static EvictionPolicy getEvictionPolicy(CacheConfig config) {
        if (config.getEvictionPolicy() == null) {
            // It will be default to LRUEviction, until we have other eviction implementations
            return new LRUEviction(config.getMaxSize());
        }
        return config.getEvictionPolicy();
    }
}

View on GitHub (pinned to 6dac31d4c2)