quarkusio/quarkus · error · IllegalStateException

Multiple RestClientBuilderFactory implementations found: ${s

Error message

Multiple RestClientBuilderFactory implementations found: ${spi} and ${instance}

What it means

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.

Source

Thrown at extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientBuilderFactory.java:30

 * configuration.
 * <p>
 * The builder instance can be further tweaked, if needed, before building the rest client proxy.
 */
public interface RestClientBuilderFactory {

    default RestClientBuilder newBuilder(Class<?> proxyType) {
        return newBuilder(proxyType,
                ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getConfigMapping(RestClientsConfig.class));
    }

    RestClientBuilder newBuilder(Class<?> proxyType, RestClientsConfig restClientsConfigRoot);

    static RestClientBuilderFactory getInstance() {
        ServiceLoader<RestClientBuilderFactory> sl = ServiceLoader.load(RestClientBuilderFactory.class);
        RestClientBuilderFactory instance = null;
        for (RestClientBuilderFactory spi : sl) {
            if (instance != null) {
                throw new IllegalStateException("Multiple RestClientBuilderFactory implementations found: "
                        + spi.getClass().getName() + " and "
                        + instance.getClass().getName());
            }
            instance = spi;
        }
        return instance;
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove one of the conflicting REST client dependencies so only one RestClientBuilderFactory provider remains
  2. Run mvn dependency:tree to find which two artifacts bring META-INF/services RestClientBuilderFactory providers and exclude one
  3. If a transitive dependency is at fault, add an <exclusion> for it in pom.xml
  4. In a shaded/fat jar, configure service file merging instead of concatenation to avoid duplicate provider lines

Example fix

// before (pom.xml)
<dependency>io.quarkus:quarkus-resteasy-client</dependency>
<dependency>org.example:legacy-jaxrs-client-bundle</dependency> <!-- also provides a factory -->
// after
<dependency>io.quarkus:quarkus-resteasy-client</dependency>
<dependency>org.example:legacy-jaxrs-client-bundle</dependency>
  <exclusions><exclusion>com.legacy:rest-provider</exclusion></exclusions>
Defensive patterns

Strategy: type-guard

Validate before calling

long providers = ServiceLoader.load(RestClientBuilderFactory.class).stream().count();
if (providers > 1) throw new IllegalStateException("Multiple RestClientBuilderFactory providers on classpath: " + providers);

Try / catch

try { RestClientBuilderFactory f = getInstance(); } catch (IllegalStateException e) { log.error("Duplicate REST client providers: {}", e.getMessage()); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/990fbda1ed19ace1. Report an issue: GitHub.