quarkusio/quarkus · error · IllegalStateException
No service definition for serviceName ${serviceName} found.
Error message
No service definition for serviceName ${serviceName} found. What it means
When a gRPC client channel uses the Stork name resolver, StorkGrpcChannel.newCall looks up the Service definition by serviceName in the Stork registry. If Stork has no service registered under that name, the call cannot be routed and an IllegalStateException is thrown immediately, before any network I/O.
Source
Thrown at extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/stork/StorkGrpcChannel.java:78
AtomicReference<ServiceInstance> ref;
}
public StorkGrpcChannel(GrpcClient client, String serviceName, GrpcClientConfiguration.StorkConfig stork,
Executor executor) {
this.client = client;
this.serviceName = serviceName;
this.stork = stork;
this.executor = executor;
this.scheduler = new ScheduledThreadPoolExecutor(stork.threads());
this.scheduler.scheduleAtFixedRate(this::refresh, stork.delay(), stork.period(), TimeUnit.SECONDS);
}
@Override
public <RequestT, ResponseT> ClientCall<RequestT, ResponseT> newCall(MethodDescriptor<RequestT, ResponseT> methodDescriptor,
CallOptions callOptions) {
Service service = Stork.getInstance().getService(serviceName);
if (service == null) {
throw new IllegalStateException("No service definition for serviceName " + serviceName + " found.");
}
Context context = new Context();
context.service = service;
// handle this calls here
Boolean measureTime = STORK_MEASURE_TIME.get();
context.measureTime = measureTime != null && measureTime;
context.ref = STORK_SERVICE_INSTANCE.get();
// The DelayedClientCall must deliver its listener callbacks on the call's
// own executor. Blocking stubs pass a per-call ThreadlessExecutor through
// CallOptions and park the calling thread draining it; if the callbacks
// (e.g. the close after a failed Stork resolution) are delivered on a
// different executor, that thread is never woken and the call hangs.
Executor callExecutor = callOptions.getExecutor() != null ? callOptions.getExecutor() : executor;
DelayedClientCall<RequestT, ResponseT> delayed = new StorkDelayedClientCall<>(callExecutor, scheduler,
Deadline.after(stork.deadline(), TimeUnit.MILLISECONDS));
View on GitHub (pinned to e1c734241f)
Solutions
- Define the service in Stork config: quarkus.stork.<serviceName>.service-discovery.type=static (or consul/kubernetes etc.) with address-list.
- Make sure the Stork service name matches the gRPC client name exactly (the value used in quarkus.grpc.clients.<name> or @GrpcClient).
- Add the required Stork service-discovery dependency (e.g. smallrye-stork-service-discovery-static / consul / kubernetes).
- Verify at startup with `Stork.getInstance().getServiceNames()` or the Stork Dev UI that the service is registered.
Example fix
// before (application.properties) quarkus.grpc.clients.hello.name-resolver=stork // after quarkus.grpc.clients.hello.name-resolver=stork quarkus.stork.hello.service-discovery.type=static quarkus.stork.hello.service-discovery.address-list=localhost:8084
Defensive patterns
Strategy: validation
Validate before calling
// verify the service is registered in Stork before issuing calls
import io.smallrye.stork.Stork;
if (Stork.getInstance().getService("hello") == null) {
throw new IllegalStateException("Stork service 'hello' not defined - add quarkus.stork.hello.service-discovery.*");
} Try / catch
try {
GreeterGrpc.GreeterBlockingStub stub = client;
stub.sayHello(req);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("No service definition")) {
throw new ConfigurationException("Add quarkus.stork.<service>.service-discovery config for " + e.getMessage());
}
throw e;
} Prevention
- Keep the Stork service name identical to the quarkus.grpc.clients key.
- Assert required Stork definitions in a @Startup bean or test.
- Use the Stork Dev UI / getServiceNames() during development to confirm registration.
When it happens
Trigger: quarkus.grpc.clients.<name>.name-resolver=stork is set (or @GrpcClient with stork) while quarkus.stork.<serviceName>.service-discovery.* is missing or the service name in the config differs from the Stork-registered name, so Stork.getInstance().getService(serviceName) returns null on the first newCall.
Common situations: Typos between the gRPC client config name and the quarkus.stork.<service> key; migrating a client to Stork without adding the service-discovery block; service name containing characters that need different casing in properties.
Related errors
- invalid configuration for a Stork Load Balancer : ${loadBala
- Failed to determine working socket addresses for service-nam
- gRPC client '${name}' cannot use both domain-socket and Stor
- Invalid @GrpcClient `${targetInfo}` - client name cannot be
- Unable to find the GrpcClientConfigProvider
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6900060d38cd8318.
Report an issue: GitHub.