quarkusio/quarkus · error · IllegalStateException

CORS cannot be configured both programmatically and in the…

Error message

CORS cannot be configured both programmatically and in the 'application.properties' file

What it means

CORS was configured both programmatically via HttpSecurity.cors(...) and statically via quarkus.http.cors.* properties in application.properties. Quarkus forbids the double configuration to avoid silently dropping one of them and throws IllegalStateException.

Solutions

  1. Remove the quarkus.http.cors.* entries from application.properties and configure CORS exclusively programmatically.
  2. Or drop the programmatic cors() call and keep the properties-based configuration.
  3. Search all config sources (application.properties, application.yaml, env vars like QUARKUS_HTTP_CORS_*) for CORS keys.
  4. Verify with dev mode startup that only one configuration source remains.

Example fix

// before
# application.properties
quarkus.http.cors=true
quarkus.http.cors.origins=*
// plus programmatic httpSecurity.cors(CORS.origins("https://app.example.com").build())
// after: keep only one source
httpSecurity.cors(CORS.origins("https://app.example.com").build());
// and delete quarkus.http.cors.* from application.properties
Defensive patterns

Strategy: validation

Validate before calling

boolean propsConfigured = ConfigProvider.getConfig().getOptionalValue("quarkus.http.cors.origins", String.class).isPresent();
if (propsConfigured) {
    throw new IllegalStateException("Remove quarkus.http.cors.* before configuring CORS programmatically");
}

Prevention

When it happens

Trigger: Calling cors() programmatically while application.properties already sets any of quarkus.http.cors.access-control-allow-credentials, access-control-max-age, headers, methods, or exposed-headers (alreadyConfiguredInAppProps == true).

Common situations: Migrating from properties-based CORS to programmatic CORS without deleting the old properties; examples/docs mixing both approaches; a framework/extension (e.g. SmallRye OpenAPI adding management origins) that populated origins and user code adding cors() too.

Related errors


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

Appendix: source

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

    }

    @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()) {
                LOG.warnf(
                        "CORS are configured programmatically, but previously configured '%s' origins are missing in the new configuration",
                        missingOrigins);
            }
        }
        corsConfig = newCorsConfig;
        return this;
    }

View on GitHub (pinned to e1c734241f)