quarkusio/quarkus · error · IllegalArgumentException

Client authentication cannot be null

Error message

Client authentication cannot be null

What it means

HttpSecurity.mTLS(ClientAuth) requires an explicit ClientAuth value to decide between REQUIRED and REQUEST behavior. A null argument cannot be mapped to any TLS client-auth mode, so Quarkus rejects it immediately with an IllegalArgumentException to fail fast rather than producing an insecure default.

Solutions

  1. Pass ClientAuth.REQUIRED or ClientAuth.REQUEST explicitly.
  2. If the value is dynamic, default it: ClientAuth mode = configured != null ? configured : ClientAuth.REQUIRED.
  3. Fix the upstream producer that returns null (missing config key, uninitialized field).

Example fix

// before
ClientAuth auth = readFromConfig(); // may be null
httpSecurity.mTLS(auth); // throws
// after
ClientAuth auth = readFromConfig();
httpSecurity.mTLS(auth != null ? auth : ClientAuth.REQUIRED);
Defensive patterns

Strategy: type-guard

Validate before calling

if (clientAuth == null) {
    clientAuth = ClientAuth.REQUIRED; // sensible default
}
httpSecurity.mTLS(clientAuth);

Type guard

ClientAuth nonNullOrDefault(ClientAuth auth) {
    return auth != null ? auth : ClientAuth.REQUIRED;
}

Try / catch

try {
    httpSecurity.mTLS(clientAuth);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("cannot be null")) {
        log.error("ClientAuth value missing; defaulting to REQUIRED");
        httpSecurity.mTLS(ClientAuth.REQUIRED);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling httpSecurity.mTLS(null), or passing a ClientAuth value read from config/custom code that resolves to null (e.g. Optional.get misuse upstream or an unset enum field).

Common situations: Deriving the ClientAuth value dynamically from properties where the key is absent; refactoring code that previously passed a constant and now passes a nullable variable.

Understand the failure class

Related errors


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

Appendix: source

Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityImpl.java:194

    @Override
    public HttpSecurity mTLS() {
        return mTLS(ClientAuth.REQUIRED);
    }

    @Override
    public HttpSecurity mTLS(String tlsConfigurationName, TlsConfiguration tlsConfiguration) {
        return mechanism(MTLS.required(tlsConfigurationName, tlsConfiguration));
    }

    @Override
    public HttpSecurity mTLS(MtlsAuthenticationMechanism mTLSAuthenticationMechanism) {
        return mechanism(mTLSAuthenticationMechanism);
    }

    @Override
    public HttpSecurity mTLS(ClientAuth tlsClientAuth) {
        if (tlsClientAuth == null) {
            throw new IllegalArgumentException("Client authentication cannot be null");
        }
        return switch (tlsClientAuth) {
            case REQUIRED -> mechanism(MTLS.required());
            case REQUEST -> mechanism(MTLS.request());
            case NONE -> throw new IllegalArgumentException("Client authentication cannot be disabled with this API");
        };
    }

    @Override
    public HttpPermission path(String... patterns) {
        if (patterns == null || patterns.length == 0) {
            throw new IllegalArgumentException("Paths must not be empty");
        }
        var httpPermission = new HttpPermissionImpl(patterns);
        httpPermissions.add(httpPermission);
        return httpPermission;
    }

View on GitHub (pinned to e1c734241f)