"오늘의 문제를, 내일의 기록으로 남깁니다."

막연한 이론보다, 구체적인 코드가 필요할 때. 직접 겪고 해결한 문제들을 기록합니다. 실무에서 부딪히는 진짜 이슈와, 내가 이해한 방식 그대로 정리한 가이드입니다.

웹개발/Spring

Spring Boot 500 Internal Server Error 원인 분석과 해결 방법

자바를잡아 2025. 8. 18. 08:00
반응형

Spring Boot 500 Internal Server Error 원인 분석과 해결 방법

Spring Boot 애플리케이션을 개발하거나 운영할 때, 500 Internal Server Error는 가장 흔하게 마주치는 오류 중 하나입니다.
500 오류는 서버 내부에서 예기치 못한 예외가 발생했음을 의미하며, 클라이언트에서는 구체적인 원인을 알 수 없습니다.
이 글에서는 Spring Boot 환경에서 500 에러가 발생하는 주요 원인과 실무적인 해결 방법을 정리합니다.

1. 500 Internal Server Error란?

HTTP 상태 코드 500은 서버가 요청을 처리하는 도중 예외가 발생했지만, 구체적인 정보를 클라이언트에 제공하지 않을 때 사용됩니다.
Spring Boot에서는 컨트롤러 내부 예외, 서비스 로직 오류, DB 쿼리 실패 등 거의 모든 런타임 예외가 500으로 반환됩니다.

2. 원인 1: NullPointerException (NPE)

Spring Boot 500 에러의 가장 흔한 원인은 NPE입니다.
DI(의존성 주입) 실패, 잘못된 파라미터 처리, null 리턴값 접근 등이 대표적입니다.


@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
    User user = userService.findById(id);
    return user.getName(); // user가 null이면 NPE 발생
}

해결 방법

  • Optional 활용
  • null 체크
  • 서비스 레이어에서 예외 처리

3. 원인 2: 잘못된 파라미터 변환

@RequestParam, @PathVariable로 받은 값이 타입 변환에 실패하면 예외가 발생합니다.


@GetMapping("/age")
public String age(@RequestParam int age) {
    return "Age: " + age;
}

여기에 문자열 ?age=abc로 요청하면 변환 오류가 발생하고 500으로 이어집니다.

해결 방법

  • 파라미터 타입 검증
  • 컨트롤러 어드바이스(@ControllerAdvice)로 예외 처리

4. 원인 3: DB 쿼리 실패

JPA, MyBatis 등에서 SQL 문법 오류나 제약 조건 위반 시 500이 발생합니다.


@Query("SELECT u FROM User u WHERE u.name = :name")
List<User> findByName(@Param("username") String name); // 파라미터명 불일치

해결 방법

  • SQL 로그 활성화로 쿼리 확인
  • JPA @Param 이름과 실제 변수명 일치

5. 원인 4: 파일 업로드/다운로드 오류

파일 경로나 권한 문제, Multipart 설정 오류로도 500이 발생할 수 있습니다.

해결 방법

  • 파일 경로 유효성 확인
  • application.yml에서 spring.servlet.multipart.max-file-size 설정

6. 원인 5: JSON 직렬화/역직렬화 오류

@ResponseBody 또는 @RequestBody에서 객체 변환 실패 시 500이 발생합니다.


@PostMapping("/user")
public void createUser(@RequestBody User user) {
    // JSON 필드명 불일치 시 변환 실패
}

7. 500 에러 해결을 위한 로그 분석 방법

  • application.properties에서 디버그 로그 활성화
    
    logging.level.root=DEBUG
    logging.level.org.springframework.web=DEBUG
    
  • stack trace에서 가장 위에 있는 원인 예외(caused by) 확인

8. 전역 예외 처리로 500 방지

Spring Boot에서는 @ControllerAdvice@ExceptionHandler로 예외를 전역 처리할 수 있습니다.


@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                             .body("서버 오류가 발생했습니다: " + e.getMessage());
    }
}

9. 해결 체크리스트

  • null 접근 여부 확인
  • 파라미터 타입/값 검증
  • DB 쿼리 로그 확인
  • 파일/네트워크 리소스 권한 확인
  • JSON 직렬화/역직렬화 필드명 일치

맺음말

Spring Boot에서 500 Internal Server Error는 서버 내부에서 발생하는 모든 예외를 포괄합니다.
따라서 단순히 "500이 떴다"는 정보만으로는 원인을 파악하기 어렵습니다.
로그 분석과 예외 처리 전략을 잘 세워두면, 운영 환경에서도 빠르게 원인을 찾고 대응할 수 있습니다.

반응형