quarkusio/quarkus · error · ServiceConfigurationError

Provider %s could not be instantiated %s

Error message

Provider %s could not be instantiated %s

What it means

This substitution emulates java.util.ServiceLoader for hard-coded provider classes in native image. createForHardCoded instantiates a provider via its no-arg constructor; if instantiation fails for any reason other than missing constructor or wrong type, it throws ServiceConfigurationError 'Provider <name> could not be instantiated <cause>'.

Source

Thrown at extensions/grpc-common/runtime/src/main/java/io/quarkus/grpc/common/runtime/graal/GrpcSubstitutions.java:36

import sun.misc.Unsafe;

@SuppressWarnings("unused")
@TargetClass(className = "io.grpc.ServiceProviders")
final class Target_io_grpc_ServiceProviders { // NOSONAR

    @Substitute
    static boolean isAndroid(ClassLoader cl) {
        return false;
    }

    @Substitute
    private static <T> T createForHardCoded(Class<T> klass, Class<?> rawClass) {
        try {
            return rawClass.asSubclass(klass).getConstructor().newInstance();
        } catch (NoSuchMethodException | ClassCastException e) {
            return null;
        } catch (Throwable t) {
            throw new ServiceConfigurationError(
                    String.format("Provider %s could not be instantiated %s", rawClass.getName(), t), t);
        }
    }

    @Substitute
    public static <T> List<T> loadAll(
            Class<T> klass,
            Iterator<T> serviceLoader,
            Supplier<Iterable<Class<?>>> hardcoded,
            final Target_io_grpc_ServiceProviders_PriorityAccessor<T> priorityAccessor) {

        // For loading classes directly instead of using SPI.

        Iterable<T> candidates;
        candidates = getCandidatesViaHardCoded(klass, hardcoded.get());
        List<T> list = new ArrayList<>();
        for (T current : candidates) {
            if (!priorityAccessor.isAvailable(current)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Inspect the chained cause and fix the provider initialization failing in native mode
  2. Register the provider's classes/resources for reflection with @RegisterForReflection or a RuntimeHints registrar
  3. Adjust the provider's initialization to be native-compatible (avoid unsupported APIs, use build-time init)
  4. Pin/update gRPC and provider versions so the provider is known to work on native image

Example fix

// before
class MyProvider extends NameResolverProvider {
    MyProvider() { loadExternalConfig(); } // fails in native
}
// after
class MyProvider extends NameResolverProvider {
    MyProvider() { /* only native-safe init */ }
}
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    Object p = klass.getDeclaredConstructor().newInstance();
} catch (Throwable t) {
    LOG.errorf("Provider %s will fail in native image: %s", klass.getName(), t);
}

Try / catch

try {
    ServiceLoader.load(NameResolverProvider.class).forEach(p -> registry.add(p));
} catch (ServiceConfigurationError e) {
    LOG.errorf(e, "Provider could not be instantiated: %s", e.getMessage());
}

Prevention

When it happens

Trigger: A hard-coded gRPC provider class (e.g. a NameResolverProvider or LoadBalancerProvider registered for native image) whose no-arg constructor exists but throws during construction in the native image.

Common situations: Provider static init performing operations unsupported in native image; provider constructor depending on missing resources/classes not registered for reflection; GraalVM build-time init clashing with runtime init.

Related errors


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