spring-projects/spring-security · error · IllegalStateException
Headers security is enabled, but no headers will be added. E
Error message
Headers security is enabled, but no headers will be added. Either add headers or disable headers security
What it means
HeadersConfigurer (headers() in HttpSecurity) is enabled by default but only functions when at least one HeaderWriter is registered. If the developer explicitly disabled all default writers (defaultsDisabled(), then removing everything) without adding any header writers, createHeaderWriterFilter() finds an empty writer list and throws IllegalStateException — the filter would do nothing useful.
Source
Thrown at config/src/main/java/org/springframework/security/config/annotation/web/configurers/HeadersConfigurer.java:285
this.hsts.disable();
this.frameOptions.disable();
return this;
}
@Override
public void configure(H http) {
HeaderWriterFilter headersFilter = createHeaderWriterFilter();
http.addFilter(headersFilter);
}
/**
* Creates the {@link HeaderWriter}.
* @return the {@link HeaderWriter}
*/
private HeaderWriterFilter createHeaderWriterFilter() {
List<HeaderWriter> writers = getHeaderWriters();
if (writers.isEmpty()) {
throw new IllegalStateException(
"Headers security is enabled, but no headers will be added. Either add headers or disable headers security");
}
HeaderWriterFilter headersFilter = new HeaderWriterFilter(writers);
headersFilter = postProcess(headersFilter);
return headersFilter;
}
/**
* Gets the {@link HeaderWriter} instances and possibly initializes with the defaults.
* @return
*/
private List<HeaderWriter> getHeaderWriters() {
List<HeaderWriter> writers = new ArrayList<>();
addIfNotNull(writers, this.contentTypeOptions.writer);
addIfNotNull(writers, this.xssProtection.writer);
addIfNotNull(writers, this.cacheControl.writer);
addIfNotNull(writers, this.hsts.writer);
addIfNotNull(writers, this.frameOptions.writer);View on GitHub (pinned to 96852e8860)
Solutions
- Add at least one header writer, e.g. http.headers().defaultsDisabled().xssProtection(...) or frameOptions(...)
- If headers are not wanted at all, call http.headers().disable() instead of leaving headers enabled with no writers
- Re-enable the defaults by removing defaultsDisabled() if the standard security headers were intended
Example fix
// before http.headers(h -> h.defaultsDisabled()); // after http.headers(h -> h.defaultsDisabled().frameOptions(fo -> fo.sameOrigin())); // or fully disable: http.headers(h -> h.disable());
Defensive patterns
Strategy: validation
Validate before calling
// before finalizing headers config
List<HeaderWriter> writers = getHeaderWriters(); // or inspect your headers lambda
if (writers.isEmpty()) {
throw new IllegalStateException("headers enabled with no writers: add one or call headers().disable()");
} Type guard
boolean hasHeaderWriters(HeadersConfigurer<HttpSecurity> h) {
return !h.getHeaderWriters().isEmpty();
} Try / catch
try {
http.headers(h -> h.defaultsDisabled().frameOptions(FrameOptionsConfig::sameOrigin));
} catch (IllegalStateException e) {
if (e.getMessage().contains("no headers will be added")) {
// either add a writer or use h.disable()
}
} Prevention
- After defaultsDisabled(), always add at least one writer
- Use .disable() rather than an empty headers() block when no headers are wanted
- Don't remove default writers one-by-one without adding replacements
When it happens
Trigger: Calling http.headers().defaultsDisabled() plus removeHeaderValueWriter / disabling each default writer with no addHeaderWriter, then starting the application context.
Common situations: Intending to disable headers entirely but using defaultsDisabled() on an enabled headers() section instead of .disable(); selectively turning off writers one by one and accidentally removing all of them.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Cannot apply {configurer} to already built object
- Cannot configure both a CorsConfigurationSource and a PreFli
- Invalid configuration that explicitly sets requireExplicitAu
- This object has already been built
- This object has not been built
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/30d8f5fa40b37df9.
Report an issue: GitHub.