quarkusio/quarkus · error · NullPointerException

Cannot attach headers to a null client

Error message

Cannot attach headers to a null client

What it means

GrpcClientUtils.attachHeaders() explicitly throws a NullPointerException when the client argument is null. The utility unwraps gRPC client proxies and attaches a Metadata interceptor, so it requires a real client instance to operate on. This is a fail-fast guard rather than a silent failure deep in proxy handling.

Source

Thrown at extensions/grpc/api/src/main/java/io/quarkus/grpc/GrpcClientUtils.java:26

/**
 * gRPC client utilities
 */
public class GrpcClientUtils {

    /**
     * Attach headers to a gRPC client.
     *
     * To make a call with headers, first invoke this method and then perform the intended call with the <b>returned</b> client
     *
     * @param client any kind of gRPC client
     * @param extraHeaders headers to attach
     * @param <T> type of the client
     * @return a client with headers attached
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static <T> T attachHeaders(T client, Metadata extraHeaders) {
        if (client == null) {
            throw new NullPointerException("Cannot attach headers to a null client");
        }

        client = getProxiedObject(client);

        if (client instanceof AbstractStub) {
            return (T) ((AbstractStub) client).withInterceptors(MetadataUtils.newAttachHeadersInterceptor(extraHeaders));
        } else if (client instanceof MutinyClient) {
            MutinyClient mutinyClient = (MutinyClient) client;
            AbstractStub stub = mutinyClient.getStub()
                    .withInterceptors(MetadataUtils.newAttachHeadersInterceptor(extraHeaders));
            return (T) ((MutinyClient) client).newInstanceWithStub(stub);
        } else {
            throw new IllegalArgumentException("Unsupported client type " + client.getClass());
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T getProxiedObject(T client) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check why the client reference is null before calling attachHeaders — verify the @GrpcClient injection point name matches a configured client
  2. Ensure the Quarkus application/ArC container is started when the utility is invoked (not plain unit tests without quarkus:test)
  3. Guard the call with a null check and fail with a clearer domain-specific message

Example fix

// before
Metadata headers = new Metadata();
MyGrpc client = null;
MyGrpc withHeaders = GrpcClientUtils.attachHeaders(client, headers); // NPE
// after
if (client == null) {
    throw new IllegalStateException("gRPC client not configured; check @GrpcClient name and quarkus.grpc.clients config");
}
MyGrpc withHeaders = GrpcClientUtils.attachHeaders(client, headers);
Defensive patterns

Strategy: validation

Validate before calling

if (client == null) {
    throw new IllegalStateException("gRPC client is null; check @GrpcClient configuration");
}
Metadata headers = new Metadata();
headers.put(Metadata.Key.of("x-key", Metadata.ASCII_STRING_MARSHALLER), "value");
T safe = GrpcClientUtils.attachHeaders(client, headers);

Type guard

boolean isUsableClient(Object c) {
    return c != null
        && (c instanceof io.grpc.stub.AbstractStub
            || c instanceof io.quarkus.grpc.runtime.MutinyClient);
}

Try / catch

try {
    T withHeaders = GrpcClientUtils.attachHeaders(client, headers);
} catch (NullPointerException e) {
    throw new IllegalStateException("Client was null — injection/config problem", e);
}

Prevention

When it happens

Trigger: Calling GrpcClientUtils.attachHeaders(null, metadata), typically when the @GrpcClient-injected bean failed to be injected (e.g. wrong service name in @GrpcClient("name") so the injection point is unsatisfied and resolved to null in non-CDI usage) or a factory method returning null was passed in.

Common situations: Misconfigured quarkus.grpc.clients.<name> properties so the client bean is not produced; passing a client obtained from a map/cache lookup that missed; calling the utility in unit tests without a running Quarkus context so the injected field is null.

Related errors


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