🔥 Launch Offer: Interview Preparation Bundle @ ₹2,499 ₹9,999 • 75% OFF. Offer expires in 🔥 Launch Offer: Interview Preparation Bundle @ ₹2,499 ₹9,999 • 75% OFF. Offer expires in Interview Preparation Bundle @ ₹2,499 ₹9,999

00:00:00 Get Bundle
home spring boot handling-validation-errors-gracefully-in-spring-boot-with-bindingresult-without-throwing-exceptions
Interview guide Spring Boot 11 sections

Handling Validation Errors Gracefully in Spring Boot with BindingResult (Without Throwing Exceptions)

Validation is one of the most important aspects of building secure and reliable REST APIs. Spring Boot makes validation simple with Bean Validation annotations like @NotNull, @Email, and…

Start reading
By javainterviewprep June 16, 2026 3 min read

Validation is one of the most important aspects of building secure and reliable REST APIs. Spring Boot makes validation simple with Bean Validation annotations like @NotNull, @Email, and @Size. However, many developers rely on exceptions to handle validation failures, which isn’t always the best approach.

In this article, we’ll explore how to use BindingResult to handle validation errors gracefully without throwing exceptions.


What is BindingResult?

BindingResult is an interface in Spring Framework that stores the results of data binding and validation.

When used immediately after a parameter annotated with @Valid or @Validated, it captures validation errors instead of allowing Spring to throw a MethodArgumentNotValidException.

This gives you complete control over how validation errors are returned to the client.


Why Use BindingResult?

By default, Spring Boot throws an exception when validation fails.

For example:

@PostMapping("/users")
public ResponseEntity<String> createUser(@Valid @RequestBody UserDto dto) {
    return ResponseEntity.ok("User Created");
}

If any validation constraint fails, Spring automatically throws:

MethodArgumentNotValidException

Although this works, sometimes you may want to:

  • Return custom error messages
  • Customize the error response format
  • Avoid global exception handling
  • Return only specific validation details

This is where BindingResult becomes useful.


Using BindingResult

Simply place BindingResult immediately after the validated object.

@PostMapping("/users")
public ResponseEntity<?> createUser(
        @Valid @RequestBody UserDto dto,
        BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return ResponseEntity.badRequest()
                .body(bindingResult.getAllErrors());
    }

    return ResponseEntity.ok("User Created Successfully");
}

Instead of throwing an exception, validation errors are now available inside the BindingResult.


Example DTO

public class UserDto {

    @NotBlank(message = "Name cannot be empty")
    private String name;

    @Email(message = "Invalid email address")
    private String email;

    @Min(value = 18, message = "Age must be at least 18")
    private int age;

    // Getters and Setters
}

Sample Invalid Request

{
    "name": "",
    "email": "abc",
    "age": 15
}

Validation Response

[
  {
    "defaultMessage": "Name cannot be empty"
  },
  {
    "defaultMessage": "Invalid email address"
  },
  {
    "defaultMessage": "Age must be at least 18"
  }
]

No exception is thrown. Your controller handles everything.


Returning Cleaner Error Messages

Instead of returning the entire error object, you can extract only the messages.

if (bindingResult.hasErrors()) {

    List<String> errors = bindingResult.getFieldErrors()
            .stream()
            .map(error -> error.getField() + ": " + error.getDefaultMessage())
            .toList();

    return ResponseEntity.badRequest().body(errors);
}

Output:

[
    "name: Name cannot be empty",
    "email: Invalid email address",
    "age: Age must be at least 18"
]

This response is much cleaner and easier for frontend applications to consume.


Useful BindingResult Methods

MethodDescription
hasErrors()Checks whether validation failed
getAllErrors()Returns all validation errors
getFieldErrors()Returns field-specific errors
getFieldError()Returns the first field error
getErrorCount()Returns the total number of validation errors

Important Rule

BindingResult must be placed immediately after the validated parameter.

✅ Correct:

public ResponseEntity<?> create(
        @Valid @RequestBody UserDto dto,
        BindingResult bindingResult)

❌ Incorrect:

public ResponseEntity<?> create(
        @Valid @RequestBody UserDto dto,
        HttpServletRequest request,
        BindingResult bindingResult)

If any parameter comes between @Valid and BindingResult, Spring will ignore the BindingResult and throw an exception instead.


When Should You Use BindingResult?

Use BindingResult when you want to:

  • Handle validation inside the controller
  • Return custom validation responses
  • Avoid using global exception handlers
  • Keep validation logic simple for smaller applications

For larger enterprise applications, many teams prefer using @ControllerAdvice with a global exception handler to centralize error handling. However, BindingResult is an excellent choice when controller-specific validation behavior is needed.


Conclusion

BindingResult provides a simple and effective way to handle validation errors without relying on exceptions. It gives you full control over the response format, making your APIs more user-friendly and easier for clients to consume.

If you need custom validation responses or want to avoid global exception handling for specific endpoints, BindingResult is a powerful feature worth adding to your Spring Boot toolkit.

Happy Coding! 🚀