{"record":{"id":"6e40284e60485328","repo":"quarkusio/quarkus","slug":"unable-to-locate-proper-constructor-for-dynamicall","errorCode":null,"errorMessage":"Unable to locate proper constructor for dynamically registered provider. Make sure the class has a no-args constructor and that it uses '@Context' for field injection if necessary.","messagePattern":"Unable to locate proper constructor for dynamically registered provider\\. Make sure the class has a no-args constructor and that it uses '@Context' for field injection if necessary\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-classic/resteasy-common/runtime/src/main/java/io/quarkus/resteasy/common/runtime/QuarkusInjectorFactory.java","lineNumber":30,"sourceCode":"import org.jboss.resteasy.spi.Failure;\nimport org.jboss.resteasy.spi.HttpRequest;\nimport org.jboss.resteasy.spi.HttpResponse;\nimport org.jboss.resteasy.spi.PropertyInjector;\nimport org.jboss.resteasy.spi.ResteasyProviderFactory;\nimport org.jboss.resteasy.spi.metadata.ResourceClass;\nimport org.jboss.resteasy.spi.metadata.ResourceConstructor;\n\nimport io.quarkus.arc.ClientProxy;\n\npublic class QuarkusInjectorFactory extends InjectorFactoryImpl {\n\n    private static final Logger log = Logger.getLogger(\"io.quarkus.resteasy.runtime\");\n\n    @SuppressWarnings(\"rawtypes\")\n    @Override\n    public ConstructorInjector createConstructor(Constructor constructor, ResteasyProviderFactory providerFactory) {\n        if (constructor == null) {\n            throw new IllegalStateException(\n                    \"Unable to locate proper constructor for dynamically registered provider. Make sure the class has a no-args constructor and that it uses '@Context' for field injection if necessary.\");\n        }\n        log.debugf(\"Create constructor: %s\", constructor);\n        return new QuarkusConstructorInjector(constructor, super.createConstructor(constructor, providerFactory));\n    }\n\n    @Override\n    public ConstructorInjector createConstructor(ResourceConstructor constructor, ResteasyProviderFactory providerFactory) {\n        log.debugf(\"Create resource constructor: %s\", constructor.getConstructor());\n        return new QuarkusConstructorInjector(constructor.getConstructor(),\n                super.createConstructor(constructor, providerFactory));\n    }\n\n    @SuppressWarnings(\"rawtypes\")\n    @Override\n    public PropertyInjector createPropertyInjector(Class resourceClass, ResteasyProviderFactory providerFactory) {\n        PropertyInjector delegate = super.createPropertyInjector(resourceClass, providerFactory);\n        return new UnwrappingPropertyInjector(delegate);","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-classic/resteasy-common/runtime/src/main/java/io/quarkus/resteasy/common/runtime/QuarkusInjectorFactory.java#L12-L48","documentation":"Quarkus replaces RESTEasy's default injector with QuarkusInjectorFactory, which relies on build-time generated constructors for JAX-RS providers. When a provider is registered dynamically at runtime (not discovered during the build), Quarkus cannot produce a synthetic constructor, so the constructor passed in is null and this IllegalStateException is thrown. It signals that the provider class cannot be instantiated by the Quarkus-supported mechanism (no-args constructor plus @Context field injection).","triggerScenarios":"Calling ResteasyProviderFactory.register(...)/registerProvider(...) with a provider class instance whose Constructor is null at createConstructor time — i.e. a provider registered programmatically at runtime rather than discovered at build time, typically one requiring constructor injection.","commonSituations":"Registering a ContainerRequestFilter, WriterInterceptor, ReaderInterceptor, MessageBodyReader/Writer, or ExceptionMapper via the ResteasyProviderFactory at runtime (e.g. in a Feature or filter chain) instead of via @Provider class discovery or quarkus.resteasy.* config; classes with only parameterized constructors.","solutions":["Register the provider statically: annotate it with @Provider so it is discovered at build time, or list it via quarkus.resteasy.filter.classes / features config properties.","Give the provider class a public no-args constructor and inject JAX-RS context objects (UriInfo, HttpHeaders, Providers) via @Context fields instead of constructor parameters.","If dynamic registration is required, register an instance created by the caller only when the provider supports no-arg construction; otherwise refactor to use CDI (@Inject) so Quarkus wires it."],"exampleFix":"// before: dynamic registration with constructor injection\npublic class MyFilter implements ContainerRequestFilter {\n    private final SomeService service;\n    public MyFilter(SomeService service) { this.service = service; }\n}\nfactory.register(new MyFilter(service)); // throws at runtime\n\n// after: build-time discovered, @Context injection\n@Provider\npublic class MyFilter implements ContainerRequestFilter {\n    @Context\n    Providers providers;\n    @Inject\n    SomeService service; // via CDI-aware setup, or use CDI.current().select(SomeService.class).get()\n    public MyFilter() {}\n}","handlingStrategy":"validation","validationCode":"static <T> void checkProviderUsable(Class<T> providerClass) throws IntrospectionException {\n    boolean hasNoArgCtor = Arrays.stream(providerClass.getConstructors())\n            .anyMatch(c -> c.getParameterCount() == 0);\n    if (!hasNoArgCtor)\n        throw new IllegalArgumentException(providerClass.getName() + \" needs a public no-arg constructor for Quarkus/RESTEasy dynamic registration\");\n}","typeGuard":"static boolean isQuarkusRegistrable(Class<?> c) {\n    try { return c.getConstructor() != null; } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    factory.register(MyFilter.class);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Unable to locate proper constructor\")) {\n        log.warn(\"Falling back to static @Provider registration for \" + MyFilter.class);\n        // register via build-time discovery instead\n    } else throw e;\n}","preventionTips":["Always give JAX-RS providers a public no-args constructor","Use @Context field injection instead of constructor injection in providers","Prefer @Provider build-time discovery over runtime ResteasyProviderFactory.register calls in Quarkus"],"tags":["resteasy","jaxrs","provider-registration","dependency-injection"],"backgroundTag":"provider-missing-no-arg-constructor","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}