REST API Error Response Structure — Best Practices
Fast recall
Quick revision
Core answer
Understanding of API design principles and client-server contracts for error communication
Returning different error structures for different exceptions, making it impossible for clients to parse errors consistently
Show a complete ErrorResponse DTO with all essential fields and mention RFC 7807 Problem Details standard for HTTP APIs
Interview-ready guide
Interview answer
For example, a missing order can return status 404 with type=https://example.test/problems/order-not-found, title=Order not found, detail=Order 42 does not exist, instance=/orders/42, and traceId=abc123. A validation response can add an errors array containing field=email and message=must be a valid address.
REST API Error Response Structure — Best Practices
Direct Answer
A good API error body has a stable machine-readable type or code, a clear human-readable message, and enough request context to diagnose the specific occurrence. HTTP status remains in the response status line. Optional fields such as instance/path, trace id, timestamp, documentation link, and field violations should be included because the contract needs them, not because every API must have the same list.
Code Example
// Standard error response for most exceptions
record ErrorResponse(
int status,
String message,
LocalDateTime timestamp,
String path
) {}
// Enhanced error response for validation failures
record ValidationErrorResponse(
int status,
String message,
LocalDateTime timestamp,
String path,
Map<String, String> fieldErrors // field name -> error message
) {}
// Usage in @ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex, HttpServletRequest request) {
var error = new ErrorResponse(404, ex.getMessage(), LocalDateTime.now(), request.getRequestURI());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ValidationErrorResponse> handleValidation(MethodArgumentNotValidException ex, HttpServletRequest request) {
Map<String, String> errors = ex.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
var error = new ValidationErrorResponse(400, "Validation failed", LocalDateTime.now(), request.getRequestURI(), errors);
return ResponseEntity.badRequest().body(error);
}
}
Common Mistakes & Pitfalls
- Inconsistent error structures: Freshers often return {"error": "message"} for one exception type and {"message": "error", "code": 404} for another — clients can't parse this reliably, breaking error handling.
- Exposing stack traces: Returning ex.getStackTrace() or ex.toString() in production leaks internal class names, file paths, and logic flow — use generic messages for unexpected errors and log details server-side only.
- Missing HTTP status in body: Relying solely on HTTP headers for status codes forces clients to check both headers and body structure differently — include status in the body for convenience.
- Not including request path: When clients make multiple parallel API calls and one fails, they can't tell which endpoint caused the error without the path field.
- Using different DTOs per exception: Creating ResourceNotFoundError, ValidationError, AuthError with different field names makes client parsing complex — use one DTO shape with optional fields.
Check your understanding
Answer these without looking back at the article.
- What is RFC 7807 Problem Details for HTTP APIs?
- How do you include field-level validation errors in your error response?
- What Spring Boot auto-configuration handles the default /error endpoint?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.