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
- Remove the quarkus.http.cors.* entries from application.properties and configure CORS exclusively programmatically.
- Or drop the programmatic cors() call and keep the properties-based configuration.
- Search all config sources (application.properties, application.yaml, env vars like QUARKUS_HTTP_CORS_*) for CORS keys.
- 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
- Pick ONE configuration style: properties OR programmatic
- Grep all config sources (properties, yaml, env vars) for quarkus.http.cors before adding programmatic config
- Document CORS location in the team's configuration conventions
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
- CORS must not be null
- no blocking executor specified
- Only a single Bouncy Castle registration can be provided.
- Shared keys for persistent logins must be more than 16…
- The trust-all option cannot be used when a trust-store is…
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)