Error responses and stack traces
Read straight from ErrorProperties.java:
private IncludeAttribute includeStacktrace = IncludeAttribute.NEVER;private IncludeAttribute includeMessage = IncludeAttribute.NEVER;Both default to NEVER. Spring Boot’s default error response carries a timestamp,
status, error name and path — and no stack trace, and not even the exception message.
That makes this a verify page, and it is worth stating plainly because it is the one place where Spring Boot’s defaults are better than both of its neighbours on this site:
| Framework | Default on an unhandled error |
|---|---|
| Spring Boot | status only — no trace, no message |
| Django | full debug page if DEBUG=True (default False) |
| Express | err.stack to the client, because NODE_ENV defaults to development |
The properties were renamed in Boot 4.0
Section titled “The properties were renamed in Boot 4.0”If you are on Boot 4.x these live under spring.web.error.*. On 3.x they are
server.error.*. Verified by diffing the application-properties appendix across
versions on 2026-08-09:
| Appendix | server.error.* |
spring.web.error.* |
|---|---|---|
| Boot 3.5.9 | 7 entries | none |
| Boot 4.0.7 | none | 7 entries |
| Boot 4.1.0 | none | 7 entries |
So every tutorial, Stack Overflow answer and internal runbook written before Boot 4 names a prefix the current appendix does not document. Check which prefix your config actually uses before assuming a setting is in force.
Worth being precise about the consequence: the default is never either way, so a
stale server.error.include-stacktrace: never on Boot 4 is a line doing nothing rather
than an exposed stack trace. The reverse — a deliberate always for a debugging
session, left behind under the old prefix — is the case where the rename actually
changes behaviour.
The full 4.x set is include-stacktrace, include-message, include-exception,
include-binding-errors, path and whitelabel.enabled, all under
spring.web.error..
# These are already the defaults. State them if you want them enforced# against a future change, but there is nothing to turn on.server: error: include-stacktrace: never include-message: never include-binding-errors: nevercurl -s https://example.com/path-that-throws | python3 -m json.toolYou should see timestamp, status, error, path — and no trace or message
key. Trigger a real exception rather than a 404; the two take different paths.
spring.web.error.include-stacktracepropertyWhen to include the trace attribute. Never by default, which makes Boot the one framework here that does not leak by default. on-param is client-triggered rather than a middle setting: it returns the trace whenever the caller appends the query parameter.
- accepts
never|always|on-param- default
never- set in
application.properties- since
Boot 4.0 — was server.error.include-stacktrace in 3.x
spring.web.error.include-messagepropertyWhen to include the message attribute. Exception messages routinely carry identifiers, SQL fragments and file paths, so always is a smaller leak than a stack trace but still a leak.
- accepts
never|always|on-param- default
never- set in
application.properties- since
Boot 4.0 — was server.error.include-message in 3.x
spring.web.error.include-exceptionpropertyWhether the response names the exception class.
- accepts
true|false- default
false- set in
application.properties- since
Boot 4.0
spring.web.error.include-binding-errorspropertyWhether validation failures are itemised in the response.
- accepts
never|always|on-param- default
never- set in
application.properties- since
Boot 4.0
spring.web.error.whitelabel.enabledpropertyThe default browser error page. On by default — it is a disclosure surface rather than a bug, and what it discloses depends on the four settings above.
- accepts
true|false- default
true- set in
application.properties- since
Boot 4.0
spring.web.error.pathpropertyPath of the error controller. This is the mapping whose absence produces the no explicit mapping for /error message.
- accepts
<path>- default
/error- set in
application.properties- since
Boot 4.0
This application has no explicit mapping for /error, so you are seeing this as a fallback.The Whitelabel Error Page, shown under the heading of the same name. It is a disclosure surface rather than a bug: the same page carries the exception type and, depending on the spring.web.error settings, the message and stack trace.
Read in: spring-boot module/spring-boot-webmvc/.../error/ErrorMvcAutoConfiguration.javaWhat to actually look for
Section titled “What to actually look for”The finding is a project that changed these, and the usual reason is debugging:
# The lines to grep for.spring.web.error.include-stacktrace: alwaysspring.web.error.include-message: alwaysinclude-stacktrace: on-param deserves a note of its own. It returns the trace when
the request carries ?trace=true — which means the behaviour is client-triggered,
and anyone who has read the documentation can request it. It is a debugging
convenience, not a middle setting, and it does not belong in production.
include-message: always looks harmless next to a stack trace, but exception messages
routinely carry the thing that failed: a file path, a SQL fragment, a host name, an
upstream URL. It is a smaller leak of the same kind.
The one that does leak by default
Section titled “The one that does leak by default”Whitelabel error pages and JSON error bodies are conservative. /actuator/heapdump
is not — see what /env actually shows. If
you are auditing information disclosure on a Spring Boot application, the Actuator
surface is where to spend the time, not the error handler.
Nothing, if they are already at the defaults.
Turning them off in an environment where developers rely on them removes a debugging affordance. The replacement is structured server-side logging with a correlation id returned to the client, so support can find the trace without the client receiving it.
Related
Section titled “Related”- Actuator sensitive values — the disclosure surface that matters here
- Express: stack traces in error responses — the same concern, opposite default