{"record":{"id":"990fbda1ed19ace1","repo":"quarkusio/quarkus","slug":"multiple-restclientbuilderfactory-implementations","errorCode":null,"errorMessage":"Multiple RestClientBuilderFactory implementations found: ${spi} and ${instance}","messagePattern":"Multiple RestClientBuilderFactory implementations found: (.+?) and (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientBuilderFactory.java","lineNumber":30,"sourceCode":" * configuration.\n * <p>\n * The builder instance can be further tweaked, if needed, before building the rest client proxy.\n */\npublic interface RestClientBuilderFactory {\n\n    default RestClientBuilder newBuilder(Class<?> proxyType) {\n        return newBuilder(proxyType,\n                ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getConfigMapping(RestClientsConfig.class));\n    }\n\n    RestClientBuilder newBuilder(Class<?> proxyType, RestClientsConfig restClientsConfigRoot);\n\n    static RestClientBuilderFactory getInstance() {\n        ServiceLoader<RestClientBuilderFactory> sl = ServiceLoader.load(RestClientBuilderFactory.class);\n        RestClientBuilderFactory instance = null;\n        for (RestClientBuilderFactory spi : sl) {\n            if (instance != null) {\n                throw new IllegalStateException(\"Multiple RestClientBuilderFactory implementations found: \"\n                        + spi.getClass().getName() + \" and \"\n                        + instance.getClass().getName());\n            }\n            instance = spi;\n        }\n        return instance;\n    }\n}\n","sourceCodeStart":12,"sourceCodeEnd":39,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientBuilderFactory.java#L12-L39","documentation":"RestClientBuilderFactory.getInstance() loads RestClientBuilderFactory implementations via java.util.ServiceLoader and expects at most one provider on the classpath. When two different provider implementations are registered (the template shows '${spi}' and '${instance}' placeholders, the real code prints the two class names), it throws IllegalStateException.","triggerScenarios":"Having two REST client provider implementations (e.g. both resteasy-client and another JAX-RS client implementation bringing its own RestClientBuilderFactory service file) on the runtime classpath of the application.","commonSituations":"Adding quarkus-resteasy-client plus another client extension (e.g. quarkus-reactive-rest-client with a conflicting provider, or manually including META-INF/services entries); fat JARs merging duplicate service files; dependency convergence issues after a version bump pulling in an extra provider.","solutions":["Remove one of the conflicting REST client dependencies so only one RestClientBuilderFactory provider remains","Run mvn dependency:tree to find which two artifacts bring META-INF/services RestClientBuilderFactory providers and exclude one","If a transitive dependency is at fault, add an <exclusion> for it in pom.xml","In a shaded/fat jar, configure service file merging instead of concatenation to avoid duplicate provider lines"],"exampleFix":"// before (pom.xml)\n<dependency>io.quarkus:quarkus-resteasy-client</dependency>\n<dependency>org.example:legacy-jaxrs-client-bundle</dependency> <!-- also provides a factory -->\n// after\n<dependency>io.quarkus:quarkus-resteasy-client</dependency>\n<dependency>org.example:legacy-jaxrs-client-bundle</dependency>\n  <exclusions><exclusion>com.legacy:rest-provider</exclusion></exclusions>","handlingStrategy":"type-guard","validationCode":"long providers = ServiceLoader.load(RestClientBuilderFactory.class).stream().count();\nif (providers > 1) throw new IllegalStateException(\"Multiple RestClientBuilderFactory providers on classpath: \" + providers);","typeGuard":null,"tryCatchPattern":"try { RestClientBuilderFactory f = getInstance(); } catch (IllegalStateException e) { log.error(\"Duplicate REST client providers: {}\", e.getMessage()); }","preventionTips":["Include only one REST client provider extension in the app","Run mvn dependency:tree after adding client-related dependencies","Check for duplicate META-INF/services entries in fat jars","Keep provider-related dependencies aligned to the same Quarkus BOM version"],"tags":["rest-client","serviceloader","classpath","duplicate-provider"],"backgroundTag":"duplicate-serviceloader-provider","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"}