본문 바로가기
💻 트러블슈팅 (에러 해결)

데이터 형식 불량! MethodArgumentNotValidException 원인과 해결법 완벽 정리

by 데브프리 2026. 6. 29.

안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다.

 

지난 포스팅에서는 프론트엔드가 보낸 JSON 데이터 자체를 해석하지 못할 때 발생하는 에러를 다루었습니다. 그렇다면 JSON 문법은 완벽해서 백엔드가 정상적으로 읽기는 했는데, 그 안의 내용물(값)이 우리가 정한 규칙에 맞지 않을 때는 어떤 에러가 발생할까요?

 

이메일 형식이어야 하는데 일반 문자열이 들어왔거나, 비밀번호가 너무 짧거나, 필수 값이 비어있을 때 브라우저에는 400 Bad Request가 뜨고 백엔드 콘솔창에는 다음과 같은 에러가 발생합니다.

 

org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public ...

 

이름이 참 길고 복잡하죠? 오늘은 데이터 유효성 검사에서 가장 많이 마주치는 'MethodArgumentNotValidException'의 원인을 아주 직관적으로 알아보고, 이를 똑똑하게 해결하는 방법까지 확실하게 정리해 드리겠습니다!

 

1. MethodArgumentNotValid 에러, 도대체 넌 누구냐? (품질 검사대 비유)

MethodArgumentNotValidException은 단어 그대로 "메서드의 매개변수(Argument)로 들어온 값이 유효하지 않다(Not Valid)"라며 스프링 부트가 데이터 통과를 거부하는 에러입니다.

스프링 부트 MethodArgumentNotValidException 에러 원인 비유
이 에러는 클라이언트가 보낸 데이터의 형태는 올바르지만, 그 내부의 세부 값들이 백엔드가 지정한 품질 기준(유효성 규칙)을 통과하지 못했을 때 발생합니다.

일상생활에 비유해 볼까요?

스프링 부트 서버는 가구 공장의 '품질 검사대'입니다. 여러분이 공장에 재료(데이터)를 보냈고, 포장 상태(JSON 문법)는 완벽했습니다. 그런데 검사관이 재료를 꺼내 자로 재어보니 "길이는 최소 10cm 이상이어야 하는데 왜 3cm밖에 안 되지?" 하고 규격 미달로 판정하여 라인을 멈춰 세운 상황입니다.

 

스프링 부트에서는 @NotBlank, @Min, @Email 같은 어노테이션을 DTO에 붙여 데이터의 규격을 지정하는데요, 들어온 값이 이 조건들을 단 하나라도 만족하지 못하면 스프링이 즉시 차단막을 내리고 이 에러를 던집니다.

 

2. 스프링 부트에서 이 에러가 발생하는 원인과 해결 방법

이 에러가 발생했다는 것은 유 유효성 검사 시스템 자체는 아주 잘 작동하고 있다는 뜻입니다. 다만 두 가지 관점에서 코드를 보완해야 합니다.

스프링 부트 예외 처리기 ExceptionHandler 구현
에러가 발생했을 때 거친 스택 트레이스 대신, 프론트엔드가 즉시 원인을 파악할 수 있도록 깔끔한 에러 메시지로 가공해 반환해 주는 것이 좋습니다.

원인: 프론트엔드의 데이터 누락 또는 규격 미달

백엔드가 @Valid를 통해 걸어둔 제약 조건을 프론트엔드가 만족시키지 못했을 때 발생합니다.

[백엔드 DTO 코드]

Java
 
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Getter;

@Getter
public class UserRegisterRequest {

    @NotBlank(message = "아이디는 필수 입력 값입니다.")
    private String username;

    @Size(min = 8, message = "비밀번호는 최소 8자 이상이어야 합니다.")
    private String password;

    @Email(message = "올바른 이메일 형식이 아닙니다.")
    private String email;
}

만약 프론트엔드에서 password를 "123"으로 보내거나 email을 "devfree" 형태로 골뱅이(@) 없이 보내면 예외가 발생합니다.

[해결 방법]: 글로벌 예외 처리기(ControllerAdvice) 구현하기

이 에러가 발생했을 때 그냥 두면 스프링 부트는 가공되지 않은 엄청난 양의 로그를 응답으로 보냅니다. 프론트엔드 개발자가 정확히 어떤 데이터가 왜 틀렸는지 쉽게 알 수 있도록 컨트롤러 가이드를 만들어 예쁜 JSON으로 내려주는 것이 실무 관례입니다.

Java
 
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice // 💡 프로젝트 전체의 에러를 한곳에서 잡아내는 대리인
public class GlobalExceptionHandler {

    // 💡 MethodArgumentNotValidException 에러가 터지면 이 메서드가 가로챕니다!
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        
        // 어떤 필드에서 어떤 에러 메시지가 발생했는지 모두 수집합니다.
        ex.getBindingResult().getFieldErrors().forEach(error -> 
            errors.put(error.getField(), error.getDefaultMessage())
        );
        
        // 400 Bad Request 에러 코드와 함께 깔끔하게 정리된 에러 맵을 반환합니다.
        return ResponseEntity.badRequest().body(errors);
    }
}

이렇게 설정을 해주면 프론트엔드에는 {"password": "비밀번호는 최소 8자 이상이어야 합니다."} 라는 명확한 알림이 전송되어 디버깅과 화면 처리가 매우 쉬워집니다.

 

3. 요약: 트러블슈팅 체크리스트

MethodArgumentNotValidException이 발생했다면 당황하지 말고 아래 3가지를 체크하세요.

  1. 컨트롤러 @Valid 확인: 컨트롤러 메서드의 매개변수 앞에 @Valid 또는 @Validated 어노테이션이 정상적으로 붙어 있는지 확인합니다. (이게 빠지면 검사 조차 안 하고 통과되어 DB 에러가 납니다.)
  2. DTO의 제약 조건 확인: 내가 DTO 클래스 변수들에 지정한 @NotBlank, @NotNull, @Min, @Max 등의 기준이 너무 엄격하지 않은지 검토합니다.
  3. 프론트엔드 전송 값 검증: 브라우저 개발자 도구의 네트워크 탭을 열어, 실제로 프론트엔드에서 보낸 값이 내가 지정한 제약 조건을 위반하고 있지 않은지 대조해 봅니다.

 

마무리

데이터가 들어오는 길목에서 발생하는 이 에러는, 우리 시스템에 불량 데이터가 침투하지 못하도록 막아주는 '보안 및 데이터 청정 보초병' 역할을 합니다.

 

에러가 났다고 당황하기보다는, 유효성 검사가 아주 튼튼하게 잘 작동하고 있음에 안도하고 프론트엔드와 데이터 규격을 꼼꼼하게 다시 맞춰보세요. 예외 처리기(ExceptionHandler)까지 깔끔하게 구현해 둔다면 여러분은 한 단계 더 성장한 백엔드 개발자가 될 것입니다.

 

오늘 준비한 트러블슈팅 가이드가 여러분의 붉은 에러 창을 깨끗하게 지워주었기를 바랍니다. 오류를 고친 경험은 여러분의 가장 큰 자산이 됩니다. 막히는 에러가 있다면 언제든 댓글로 남겨주세요.

 

지금까지 데브프리였습니다. 감사합니다!