quarkusio/quarkus · error · IllegalArgumentException

CORS must not be null

Error message

CORS must not be null

What it means

The programmatic HttpSecurity API rejects a null CORS argument. HttpSecurity.cors(CORS) performs an explicit null check and throws IllegalArgumentException before merging with the properties-based CORS config.

Source

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

        this.corsConfig = vertxHttpConfig == null ? null : vertxHttpConfig.cors();
        this.csrf = null;
    }

    @Override
    public HttpSecurity cors(String origin) {
        Objects.requireNonNull(origin);
        return cors(Set.of(origin));
    }

    @Override
    public HttpSecurity cors(Set<String> origins) {
        return cors(CORS.origins(origins).build());
    }

    @Override
    public HttpSecurity cors(CORS cors) {
        if (cors == null) {
            throw new IllegalArgumentException("CORS must not be null");
        }
        final boolean alreadyConfiguredInAppProps = corsConfig.accessControlAllowCredentials().isPresent()
                || corsConfig.accessControlMaxAge().isPresent()
                || corsConfig.headers().isPresent()
                || corsConfig.methods().isPresent()
                || corsConfig.exposedHeaders().isPresent();
        if (alreadyConfiguredInAppProps) {
            throw new IllegalStateException(
                    "CORS cannot be configured both programmatically and in the 'application.properties' file");
        }
        final CORSConfig newCorsConfig = (CORSConfig) cors;
        if (!corsConfig.origins().orElse(List.of()).isEmpty()) {
            // for example SmallRye OpenAPI extension adds a management URL to 'origins'
            // and we want users know that they are loosing some configuration
            final List<String> newOrigins = newCorsConfig.origins().orElse(List.of());
            final String missingOrigins = corsConfig.origins().get().stream()
                    .filter(origin -> !newOrigins.contains(origin)).collect(Collectors.joining(","));
            if (!missingOrigins.isEmpty()) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Always pass a constructed CORS object: HttpSecurity.CORS.origins(...).build().
  2. Guard the call site and skip cors() entirely when no CORS configuration is intended instead of passing null.
  3. Check builder code for paths that can return null and default to an empty CORS config instead.

Example fix

// before
httpSecurity.cors(maybeCors); // maybeCors == null -> IllegalArgumentException
// after
if (maybeCors != null) {
    httpSecurity.cors(maybeCors);
}
Defensive patterns

Strategy: type-guard

Type guard

static boolean isValidCors(HttpSecurity.CORS c) { return c != null; }
// usage: if (isValidCors(cors)) httpSecurity.cors(cors);

Prevention

When it happens

Trigger: Calling httpSecurity.cors(null) (or cors(CORS.origins(...).build() returning null via custom builder misuse) in programmatic security setup code.

Common situations: Programmatic security configuration in a @QuarkusMain / startup hook where the CORS builder is conditionally built and can yield null; refactors that pass an unset/optional CORS value.

Related errors


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