0
0
SpringbootDebug / FixBeginner · 4 min read

How to Handle 500 Internal Server Error in Spring Boot

In Spring Boot, you handle 500 Internal Server Error by creating a global exception handler using @ControllerAdvice and @ExceptionHandler. This lets you catch unexpected exceptions and return a friendly error response instead of a raw server error.
🔍

Why This Happens

A 500 Internal Server Error happens when your Spring Boot application throws an unhandled exception during request processing. This means the server encountered a problem it didn't expect and couldn't recover from.

For example, if your controller method throws a NullPointerException or any runtime exception without handling it, Spring Boot returns a 500 error by default.

java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @GetMapping("/error500")
    public String causeError() {
        String text = null;
        // This will throw NullPointerException causing 500 error
        return text.toLowerCase();
    }
}
Output
HTTP/1.1 500 Internal Server Error { "timestamp": "2024-06-01T12:00:00", "status": 500, "error": "Internal Server Error", "message": "NullPointerException", "path": "/error500" }
🔧

The Fix

To fix this, create a global exception handler class annotated with @ControllerAdvice. Inside, use @ExceptionHandler(Exception.class) to catch all exceptions and return a custom response. This prevents raw 500 errors and lets you send friendly messages or error codes.

java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Map<String, Object>> handleAllExceptions(Exception ex) {
        Map<String, Object> body = new HashMap<>();
        body.put("timestamp", LocalDateTime.now().toString());
        body.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
        body.put("error", "Internal Server Error");
        body.put("message", ex.getMessage());
        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
Output
HTTP/1.1 500 Internal Server Error { "timestamp": "2024-06-01T12:05:00", "status": 500, "error": "Internal Server Error", "message": "Cannot invoke \"String.toLowerCase()\" because \"text\" is null" }
🛡️

Prevention

To avoid unexpected 500 errors, always validate inputs and handle exceptions locally when possible. Use @ControllerAdvice for global error handling to catch unhandled exceptions gracefully. Also, write unit tests to cover error cases and use logging to track issues early.

Following these practices helps keep your app stable and user-friendly.

⚠️

Related Errors

Other common HTTP errors include:

  • 400 Bad Request: Happens when client sends invalid data. Fix by validating inputs.
  • 404 Not Found: When requested resource is missing. Fix by checking URL paths and resource existence.
  • 403 Forbidden: When user lacks permission. Fix by configuring security rules properly.

Key Takeaways

Use @ControllerAdvice with @ExceptionHandler to catch and handle 500 errors globally.
Unhandled exceptions in controllers cause 500 Internal Server Errors by default.
Return clear, user-friendly error responses instead of raw server errors.
Validate inputs and handle exceptions locally to reduce unexpected errors.
Logging and testing help detect and prevent 500 errors early.