quarkusio/quarkus · error · IllegalStateException
Unable to find the GrpcClientConfigProvider
Error message
Unable to find the GrpcClientConfigProvider
What it means
Channels.createChannel resolves gRPC client configuration at runtime through the GrpcClientConfigProvider bean registered in the CDI container. If the Arc container has no GrpcClientConfigProvider bean available, channel creation cannot read quarkus.grpc.clients.* config and fails fast with IllegalStateException. This normally means the Quarkus gRPC deployment-time wiring did not run (e.g. code executed outside a Quarkus application, or in tests without the gRPC extension).
Source
Thrown at extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/Channels.java:88
import io.vertx.grpcio.client.GrpcIoClient;
import io.vertx.grpcio.client.GrpcIoClientChannel;
@SuppressWarnings({ "OptionalIsPresent" })
public class Channels {
private static final Logger LOGGER = Logger.getLogger(Channels.class.getName());
private Channels() {
// Avoid direct instantiation
}
@SuppressWarnings("rawtypes")
public static Channel createChannel(String name, Set<String> perClientInterceptors) throws Exception {
ArcContainer container = Arc.container();
InstanceHandle<GrpcClientConfigProvider> instance = container.instance(GrpcClientConfigProvider.class);
if (!instance.isAvailable()) {
throw new IllegalStateException("Unable to find the GrpcClientConfigProvider");
}
instance.get();
SmallRyeConfig config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class);
GrpcConfiguration grpcConfig = config.getConfigMapping(GrpcConfiguration.class);
GrpcClientConfiguration clientConfig = grpcConfig.clients().get(name);
String host = clientConfig.host();
int port = clientConfig.port();
if (LaunchMode.current() == LaunchMode.TEST) {
if (clientConfig.testPort().isPresent()) {
port = clientConfig.testPort().getAsInt();
} else {
boolean clientUsesTls = clientConfig.tlsConfigurationName().isPresent() || clientConfig.tls().enabled()
|| (clientConfig.plainText().isPresent() && !clientConfig.plainText().get());
ValueRegistry valueRegistry = container.instance(ValueRegistry.class).get();
HttpServer httpServer = valueRegistry.get(HttpServer.HTTP_SERVER);
int actualPort = clientUsesTls ? httpServer.getSecurePort() : httpServer.getPort();View on GitHub (pinned to e1c734241f)
Solutions
- Run the code inside a Quarkus application / @QuarkusTest so the GrpcClientConfigProvider bean is registered by the gRPC extension.
- Obtain channels through the supported API: @Inject GrpcClient / Mutiny gRPC service stubs instead of calling Channels.createChannel manually.
- Add the quarkus-grpc extension dependency to the module (the provider is registered by the deployment module at build time).
- If in a test, annotate with @QuarkusTest and let the container start before creating clients.
Example fix
// before
Channel ch = Channels.createChannel("hello", Set.of());
// after
@QuarkusTest
class MyTest {
@InjectMock
// or better:
@GrpcClient("hello")
Greeter greeter; // managed channel created by Quarkus
} Defensive patterns
Strategy: type-guard
Type guard
boolean grpcConfigAvailable() {
io.quarkus.arc.ArcContainer container = io.quarkus.arc.Arc.container();
return container != null
&& container.instance(io.quarkus.grpc.runtime.config.GrpcClientConfigProvider.class).isAvailable();
} Try / catch
try {
Channel ch = Channels.createChannel("hello", Set.of());
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("GrpcClientConfigProvider")) {
throw new IllegalStateException("Channels.createChannel requires a running Quarkus app; use @GrpcClient injection instead", e);
}
throw e;
} Prevention
- Never call Channels.createChannel outside a started Quarkus container.
- Always obtain gRPC clients via @GrpcClient injection or Quarkus-managed beans.
- Use @QuarkusTest in tests that need real channels.
When it happens
Trigger: Calling Channels.createChannel(name, perClientInterceptors) directly (or via code paths that build channels manually) when Arc.container().instance(GrpcClientConfigProvider.class).isAvailable() is false — typically running in a plain JUnit test, a non-Quarkus runtime, or an application where the gRPC deployment processor never registered the provider bean.
Common situations: Unit tests that instantiate gRPC clients without @QuarkusTest; using the gRPC runtime classes in a library consumed by a non-Quarkus app; startup ordering where the container is not yet initialized (Arc.container() null).
Related errors
- Unable to retrieve the gRPC Channel ${name}
- Invalid @GrpcClient `${targetInfo}` - client name cannot be
- Interceptor class ${interceptorClass} is not a CDI bean. Onl
- Unable to find the TLS configuration ${tlsConfigurationName}
- Trust options have already been set
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/07f6abade2d89659.
Report an issue: GitHub.