This affects 6.1.x and later. Here's a minimal Boot app that should illustrate the problem:

package com.example.gh_37101;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import org.springframework.validation.beanvalidation.BeanValidationPostProcessor;

import com.example.gh_37101.Gh37101Application.Example.Exclude;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Pattern;

@SpringBootConfiguration
public class Gh37101Application {

    @Bean
    static BeanValidationPostProcessor beanValidationPostProcess() {
        return new BeanValidationPostProcessor();
    }

    @Bean
    Example example() {
        Exclude exclude = new Exclude();
        exclude.setHttpStatus(List.of("invalid"));
        Example example = new Example();
        example.setExclude(List.of(exclude));
        return example;
    }

    public static void main(String[] args) {
        SpringApplication.run(Gh37101Application.class, args);
    }

    @Validated
    class Example {

        @Valid
        private List<Exclude> exclude = new ArrayList<>();

        public List<Exclude> getExclude() {
            return exclude;
        }

        public void setExclude(List<Exclude> exclude) {
            this.exclude = exclude;
        }

        public static class Exclude {

            private List<@Pattern(regexp="^([1-5][x|X]{2}|[1-5][0-9]{2})\\$") String> httpStatus;

            public List<String> getHttpStatus() {
                return httpStatus;
            }

            public void setHttpStatus(List<String> httpStatus) {
                this.httpStatus = httpStatus;
            }

        }

    }

}

Running it on the JVM will result in a start up failure as the validation fails:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v3.2.11)

2024-11-04T14:26:29.538Z  INFO 59233 --- [           main] c.example.gh_37101.Gh37101Application    : Starting Gh37101Application using Java 17.0.12 with PID 59233 (/Users/awilkinson/dev/temp/gh-37101/build/classes/java/main started by awilkinson in /Users/awilkinson/dev/temp/gh-37101)
2024-11-04T14:26:29.540Z  INFO 59233 --- [           main] c.example.gh_37101.Gh37101Application    : No active profile set, falling back to 1 default profile: "default"
2024-11-04T14:26:29.744Z  WARN 59233 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'example' defined in com.example.gh_37101.Gh37101Application: Bean state is invalid: exclude[0].httpStatus[0].<list element> - must match "^([1-5][x|X]{2}|[1-5][0-9]{2})\$"
2024-11-04T14:26:29.762Z ERROR 59233 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'example' defined in com.example.gh_37101.Gh37101Application: Bean state is invalid: exclude[0].httpStatus[0].<list element> - must match "^([1-5][x|X]{2}|[1-5][0-9]{2})\$"
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) ~[spring-context-6.1.14.jar:6.1.14]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.14.jar:6.1.14]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.11.jar:3.2.11]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.11.jar:3.2.11]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.2.11.jar:3.2.11]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.2.11.jar:3.2.11]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.2.11.jar:3.2.11]
        at com.example.gh_37101.Gh37101Application.main(Gh37101Application.java:35) ~[main/:na]
Caused by: org.springframework.beans.factory.BeanInitializationException: Bean state is invalid: exclude[0].httpStatus[0].<list element> - must match "^([1-5][x|X]{2}|[1-5][0-9]{2})\$"
        at org.springframework.validation.beanvalidation.BeanValidationPostProcessor.doValidate(BeanValidationPostProcessor.java:127) ~[spring-context-6.1.14.jar:6.1.14]
        at org.springframework.validation.beanvalidation.BeanValidationPostProcessor.postProcessBeforeInitialization(BeanValidationPostProcessor.java:91) ~[spring-context-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:422) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1798) ~[spring-beans-6.1.14.jar:6.1.14]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.14.jar:6.1.14]
        ... 14 common frames omitted

Running as a native image will succeed:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v3.2.11)

2024-11-04T14:28:53.031Z  INFO 59751 --- [           main] c.example.gh_37101.Gh37101Application    : Starting AOT-processed Gh37101Application using Java 22.0.1 with PID 59751 (/Users/awilkinson/dev/temp/gh-37101/build/native/nativeCompile/gh-37101 started by awilkinson in /Users/awilkinson/dev/temp/gh-37101)
2024-11-04T14:28:53.032Z  INFO 59751 --- [           main] c.example.gh_37101.Gh37101Application    : No active profile set, falling back to 1 default profile: "default"
2024-11-04T14:28:53.038Z  INFO 59751 --- [           main] c.example.gh_37101.Gh37101Application    : Started Gh37101Application in 0.023 seconds (process running for 0.035)

Running as a native image succeeds because AOT processing does not generate any metadata for the @Pattern container element constraint. It's missed both because the cascade on exclude isn't considered and because container element constraints are not considered.

Comment From: wilkinsona

Thanks for this, @sdeleuze. Given that you consider this to be an enhancement, am I right to assume that it won't be backported to 6.1.x?

Comment From: sdeleuze

Yeah, the change is more involved than expected, so I chose to make it 6.2+ only after discussing with the team.