{"record":{"id":"97b83759d902262a","repo":"quarkusio/quarkus","slug":"cache-key-generator-instantiation-failed","errorCode":null,"errorMessage":"Cache key generator instantiation failed","messagePattern":"Cache key generator instantiation failed","errorType":"exception","errorClass":"CacheException","httpStatus":null,"severity":"error","filePath":"extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheInterceptor.java","lineNumber":219,"sourceCode":"            try {\n                return keyGen.get().generate(method, methodParameterValues);\n            } finally {\n                Bean<T> bean = keyGen.getBean();\n                if (bean != null && Dependent.class.equals(bean.getScope())) {\n                    // Destroy @Dependent beans afterwards\n                    keyGen.destroy();\n                }\n            }\n        } else {\n            try {\n                LOGGER.tracef(\"Creating a new cache key generator instance [class=%s]\", keyGeneratorClass.getName());\n                return keyGeneratorClass.getConstructor().newInstance().generate(method, methodParameterValues);\n            } catch (NoSuchMethodException e) {\n                // This should never be thrown because the default constructor availability is checked at build time.\n                throw new CacheException(\"No default constructor found in cache key generator [class=\"\n                        + keyGeneratorClass.getName() + \"]\", e);\n            } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {\n                throw new CacheException(\"Cache key generator instantiation failed\", e);\n            }\n        }\n    }\n\n    protected static ReturnType determineReturnType(Class<?> returnType) {\n        if (Uni.class.isAssignableFrom(returnType)) {\n            return ReturnType.Uni;\n        }\n        if (CompletionStage.class.isAssignableFrom(returnType)) {\n            return ReturnType.CompletionStage;\n        }\n        return ReturnType.NonAsync;\n    }\n\n    protected Uni<?> asyncInvocationResultToUni(Object invocationResult, ReturnType returnType) {\n        if (returnType == ReturnType.Uni) {\n            return (Uni<?>) invocationResult;\n        } else if (returnType == ReturnType.CompletionStage) {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheInterceptor.java#L201-L237","documentation":"When no CDI bean of the configured key generator class is resolvable, CacheInterceptor reflectively instantiates it via its default constructor. If that reflective instantiation fails (InstantiationException, IllegalAccessException, or InvocationTargetException from the constructor), it is wrapped in a CacheException.","triggerScenarios":"A @CacheKeyGenerator class whose constructor throws an exception, is not public, or is abstract/non-instantiable, and which is not registered as a CDI bean (so the reflective path is taken).","commonSituations":"Key generator with a constructor that does heavy init and throws; inner (non-static) classes whose implicit outer reference makes the no-arg constructor inaccessible; abstract base class mistakenly referenced in @CacheResult(keyGenerator=...).","solutions":["Make the key generator a public, static, concrete class with a public no-arg constructor whose body cannot throw.","Register it as a @Dependent CDI bean so the interceptor uses the managed instance path instead of reflection.","Inspect the wrapped cause (e.getCause()) to find what the constructor threw."],"exampleFix":"// before\npublic class MyKeyGen {\n    public MyKeyGen() { loadFromDb(); } // throws\n}\n\n// after\n@Dependent\npublic class MyKeyGen implements CacheKeyGenerator {\n    public MyKeyGen() { }\n    public Object generate(Method m, Object... params) { ... }\n}","handlingStrategy":"try-catch","validationCode":"Class<?> gen = MyKeyGen.class;\nif (java.lang.reflect.Modifier.isAbstract(gen.getModifiers())) {\n    throw new IllegalStateException(\"Key generator must be concrete\");\n}\ngen.getDeclaredConstructor(); // fails fast if no no-arg ctor\nif (!java.lang.reflect.Modifier.isPublic(gen.getModifiers())) {\n    throw new IllegalStateException(\"Key generator must be public\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Object key = interceptor.generateKey(gen, method, params);\n} catch (CacheException e) {\n    LOGGER.error(\"Key generator failed\", e.getCause());\n    throw e;\n}","preventionTips":["Make key generators public static concrete classes","Keep no-arg constructors free of throwing side effects","Register generators as CDI beans to avoid the reflective path"],"tags":["quarkus","cache","reflection","key-generator","cdi"],"backgroundTag":"key-generator-instantiation-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}