Spring Boot
JSON error response
Rest Controller
error handling
custom error response

Modify default JSON error response from Spring Boot Rest Controller

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Spring Boot's default JSON error response is useful for development, but many APIs need a cleaner and more stable error contract. The usual way to achieve that is not to patch the response ad hoc in each controller, but to centralize error handling in one place. In practice, @RestControllerAdvice is the most maintainable starting point.

Use @RestControllerAdvice for API Error Shaping

A global exception handler lets you map exceptions to one consistent JSON structure.

java
1import java.time.Instant;
2import java.util.Map;
3import org.springframework.http.HttpStatus;
4import org.springframework.http.ResponseEntity;
5import org.springframework.web.bind.annotation.ExceptionHandler;
6import org.springframework.web.bind.annotation.RestControllerAdvice;
7
8@RestControllerAdvice
9public class ApiExceptionHandler {
10
11    @ExceptionHandler(IllegalArgumentException.class)
12    public ResponseEntity<Map<String, Object>> handleIllegalArgument(IllegalArgumentException ex) {
13        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of(
14            "timestamp", Instant.now().toString(),
15            "code", "BAD_REQUEST",
16            "message", ex.getMessage()
17        ));
18    }
19}

This immediately replaces the default response for the handled exception type with your custom payload.

Return a Stable Error DTO Instead of Ad Hoc Maps

Maps are fine for quick examples, but a dedicated error response class is easier to version and document.

java
1public record ApiError(
2    String code,
3    String message,
4    String path
5) {}

Then return that DTO from your advice methods. This makes the API contract explicit and easier for clients to rely on.

Handle Validation Errors Separately

Validation failures often need a more detailed payload than generic exceptions. For example, field-level validation errors may need to include which input fields failed and why.

That is a good reason to have separate handlers for validation-related exceptions rather than one generic catch-all.

Clients benefit from this because validation problems are usually actionable. A generic "bad request" message is much less useful than a stable list of invalid fields and reasons.

Know When to Customize Error Attributes

@RestControllerAdvice handles exceptions raised through normal controller flow. If you also want to reshape framework-level fallback errors, such as unmapped routes or deeper error dispatch behavior, customizing Boot's error attributes or error controller may be necessary.

That is a second layer of customization, not the first one to reach for.

This distinction matters when teams try to customize one error path and then wonder why some framework-generated responses still use the default shape. Not every error enters through the same code path.

Avoid Leaking Internal Details

Default error payloads can include exception names, stack-trace-related hints, or internal messages that are useful during debugging but not appropriate for public APIs. A custom error handler gives you control over what clients see.

That is not just about aesthetics. It is part of API stability and security hygiene.

It also helps documentation. Once your error shape is stable, it can be documented and tested like any other part of the API contract.

That stability is often more valuable to API consumers than the specific wording of any one message, because clients can code against predictable fields. Consistency is the big win.

It also simplifies monitoring. When every failure response exposes the same core fields, logs, dashboards, and client-side telemetry become much easier to aggregate and interpret.

Common Pitfalls

  • Duplicating response-shaping logic across many controllers instead of using global advice.
  • Returning different JSON error shapes for similar failures.
  • Exposing internal exception messages directly to clients without review.
  • Using a generic catch-all handler and losing useful status-code distinctions.
  • Assuming controller advice alone covers every error path in the framework.

Summary

  • The clean way to customize Spring Boot JSON error responses is usually @RestControllerAdvice.
  • Use a stable DTO or response schema instead of ad hoc error payloads.
  • Handle validation errors with dedicated logic when clients need field-level detail.
  • Customize deeper error infrastructure only when controller advice is not enough.
  • Treat error responses as part of the API contract, not just a debugging convenience.

Course illustration
Course illustration

All Rights Reserved.