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

  1. Define the service in Stork config: quarkus.stork.<serviceName>.service-discovery.type=static (or consul/kubernetes etc.) with address-list.
  2. Make sure the Stork service name matches the gRPC client name exactly (the value used in quarkus.grpc.clients.<name> or @GrpcClient).
  3. Add the required Stork service-discovery dependency (e.g. smallrye-stork-service-discovery-static / consul / kubernetes).
  4. 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

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


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