Spring Framework 6.1.3 introduced a regression in MVC where validation error details are not returned anymore for REST endpoints in certain cases. These settings in Spring Boot become ineffective:

server.error.include-binding-errors=always
server.error.include-message=always

I created a minimal sample application to demonstrate the issue: https://github.com/notizklotz/spring-boot-322-validation-regression

The bug appears at least in these conditions: - Spring Boot 3.2.2 and 3.2.3 (Spring Framework 6.1.3 and 6.1.4) - One of the method parameters has a jakarta.validation.constraints constraint. - Validation on a another parameter fails, which is a @Valid annotated Pojo.

With Spring Boot 3.2.0 and 3.2.1 (Spring Framework 6.1.1 and 6.1.2) the validation error of the Pojo results in a MethodArgumentNotValidException:

2024-03-08T07:41:14.526+01:00  WARN 38155 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [1] in public void com.example.demo.DemoApplication.withConstraintOnPathVariable(java.lang.String,com.example.demo.DemoApplication$RequestData): [Field error in object 'requestData' on field 'propertyA': rejected value []; codes [NotBlank.requestData.propertyA,NotBlank.propertyA,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [requestData.propertyA,propertyA]; arguments []; default message [propertyA]]; default message [must not be blank]] ]

With Spring Boot 3.2.2 and 3.2.3 (Spring Framework 6.1.3 and 6.1.4) this results in a HandlerMethodValidationException:

2024-03-08T07:40:18.447+01:00  WARN 37706 --- [nio-8080-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolved [org.springframework.web.method.annotation.HandlerMethodValidationException: 400 BAD_REQUEST "Validation failure"]

This issue seems to be related to the changes made for #32007

Comment From: quaff

@notizklotz Your sample application code repository is private.

Comment From: notizklotz

@quaff I made it public now. Sorry about that!

Comment From: rstoyanchev

Thanks for the sample.

Although it does look like it, it's not actually a regression. Given this method signature:

@PostMapping("/api/{mypath}/with-constraint")
public void withConstraintOnPathVariable(
        @PathVariable @Pattern(regexp =  "[a-z0-9-]+") String mypath,
        @RequestBody @Valid RequestData mydata) {
}

Method validation applies, and the @RequestBody resolver should recognize that, and refrain from validating individually, and defer to method validation instead, or otherwise it leads to validation being performed twice, and also to raising different exceptions, MethodArgumentNotValidException vs MethodValidationException, depending on whether one or both parameters have validation issues.

In 6.1.2 the resolver applies validation, not by intent, and raises MethodArgumentValidation, precluding the use of method validation. The cause is explained in https://github.com/spring-projects/spring-framework/issues/31711#issuecomment-1860589421.

In 6.1.3, the @RequestBody resolver correctly defers to method validation, and that results in a MethodValidationException with validation errors for all parameters. The actual issue to resolve here is a missing feature in Spring Boot's error response support that wasn't noticed until now. I've created https://github.com/spring-projects/spring-boot/issues/39858.

In the mean time, as of Spring Framework 6.0 we have enhanced support for RFC 7807 error responses, and ResponseEntityExceptionHandler (included with spring.mvc.problemdetails.enabled) to render error responses with details. The Boot error responses are really meant to be more of a fallback for unresolved errors, but historically we lacked a concrete format for error responses. The RFC 7807 response support provides more control over the details of validation and binding result messages via ResourceBundle's, or via code if necessary (e.g. overriding methods in ResponseEntityExceptionHandler), and HandlerMethodValidationException has a Visitor to render validation errors by parameter type, see the Validation section.

Comment From: notizklotz

Thanks a lot for your elaborate answer!

Comment From: simonzhong1985

@notizklotz what should we do to get error details as for HandlerMethodValidationException? thanks.