Close

Spring Boot - @ConfigurationProperties Cascaded Validation by using @Valid

[Last Updated: Oct 29, 2025]

In the last example, we saw how to use JSR 303/349 validation annotations with @ConfigurationProperties. In following example, we will see how to validate nested (cascaded) configuration properties by using @Valid annotation.

Example

The external properties

src/main/resources/application.properties

spring.main.banner-mode=off 
spring.main.logStartupInfo=false
app.main-screen-properties.refresh-rate=15
app.main-screen-properties.width=10
app.main-screen-properties.height=400
app.admin-contact-number.value=111-111-111
app.admin-contact-number.type=personal

@ConfigurationProperties class

@Component
@ConfigurationProperties("app")
@Validated
public class MyAppProperties {
  @NotNull
  @Valid
  private MainScreenProperties mainScreenProperties;

  @NotNull
  @Valid
  private PhoneNumber adminContactNumber;
    .............
}
public class PhoneNumber {
  @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}")
  private String value;
  @Pattern(regexp = "(?i)cell|house|work")
  private String type;
    .............
}
public class MainScreenProperties {
  @Min(1)
  private int refreshRate;
  @Min(50)
  @Max(1000)
  private int width;
  @Min(50)
  @Max(600)
  private int height;
    .............
}

We purposely added such values in the external properties file that are expected to fail per above validation annotations. This is to see whether the cascaded validation is performed as expected.

The Main class

@SpringBootApplication
public class ExampleMain {

  public static void main(String[] args) throws InterruptedException {
      ConfigurableApplicationContext context = SpringApplication.run(ExampleMain.class, args);
      MyAppProperties bean = context.getBean(MyAppProperties.class);
      System.out.println(bean);
  }
}

Output

2025-10-29 14:07:10.807  INFO 2980 --- [mpleMain.main()] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@666a175f: startup date [Wed Oct 29 14:07:10 CST 2025]; root of context hierarchy
2025-10-29 14:07:11.035 WARN 2980 --- [mpleMain.main()] o.h.v.m.ParameterMessageInterpolator : HV000184: ParameterMessageInterpolator has been chosen, EL interpolation will not be supported
2025-10-29 14:07:11.090 WARN 2980 --- [mpleMain.main()] o.h.v.m.ParameterMessageInterpolator : HV000184: ParameterMessageInterpolator has been chosen, EL interpolation will not be supported
2025-10-29 14:07:11.153 ERROR 2980 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Properties configuration failed validation
2025-10-29 14:07:11.153 ERROR 2980 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Field error in object 'app' on field 'adminContactNumber.type': rejected value [personal]; codes [Pattern.app.adminContactNumber.type,Pattern.adminContactNumber.type,Pattern.type,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.type,adminContactNumber.type]; arguments []; default message [adminContactNumber.type],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@7da4250d]; default message [must match "(?i)cell|house|work"]
2025-10-29 14:07:11.153 ERROR 2980 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Field error in object 'app' on field 'adminContactNumber.value': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber.value,Pattern.adminContactNumber.value,Pattern.value,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.value,adminContactNumber.value]; arguments []; default message [adminContactNumber.value],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@19fc2c37]; default message [must match "\d{3}-\d{3}-\d{4}"]
2025-10-29 14:07:11.153 ERROR 2980 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Field error in object 'app' on field 'mainScreenProperties.width': rejected value [10]; codes [Min.app.mainScreenProperties.width,Min.mainScreenProperties.width,Min.width,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.mainScreenProperties.width,mainScreenProperties.width]; arguments []; default message [mainScreenProperties.width],50]; default message [must be greater than or equal to 50]
2025-10-29 14:07:11.154 WARN 2980 --- [mpleMain.main()] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myAppProperties': Could not bind properties to MyAppProperties (prefix=app, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 3 errors
Field error in object 'app' on field 'adminContactNumber.type': rejected value [personal]; codes [Pattern.app.adminContactNumber.type,Pattern.adminContactNumber.type,Pattern.type,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.type,adminContactNumber.type]; arguments []; default message [adminContactNumber.type],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@7da4250d]; default message [must match "(?i)cell|house|work"]
Field error in object 'app' on field 'adminContactNumber.value': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber.value,Pattern.adminContactNumber.value,Pattern.value,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.value,adminContactNumber.value]; arguments []; default message [adminContactNumber.value],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@19fc2c37]; default message [must match "\d{3}-\d{3}-\d{4}"]
Field error in object 'app' on field 'mainScreenProperties.width': rejected value [10]; codes [Min.app.mainScreenProperties.width,Min.mainScreenProperties.width,Min.width,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.mainScreenProperties.width,mainScreenProperties.width]; arguments []; default message [mainScreenProperties.width],50]; default message [must be greater than or equal to 50]
2025-10-29 14:07:11.157 INFO 2980 --- [mpleMain.main()] utoConfigurationReportLoggingInitializer :

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2025-10-29 14:07:11.159 ERROR 2980 --- [mpleMain.main()] o.s.b.d.LoggingFailureAnalysisReporter :

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target MyAppProperties{
mainScreenProperties=MainScreenProperties{refreshRate=15, width=10, height=400}, adminContactNumber=PhoneNumber{value='111-111-111', type='personal'}
} failed:

Property: app.adminContactNumber.type
Value: personal
Reason: must match "(?i)cell|house|work"

Property: app.adminContactNumber.value
Value: 111-111-111
Reason: must match "\d{3}-\d{3}-\d{4}"

Property: app.mainScreenProperties.width
Value: 10
Reason: must be greater than or equal to 50


Action:

Update your application's configuration

[WARNING]
java.lang.reflect.InvocationTargetException
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myAppProperties': Could not bind properties to MyAppProperties (prefix=app, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 3 errors
Field error in object 'app' on field 'adminContactNumber.type': rejected value [personal]; codes [Pattern.app.adminContactNumber.type,Pattern.adminContactNumber.type,Pattern.type,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.type,adminContactNumber.type]; arguments []; default message [adminContactNumber.type],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@7da4250d]; default message [must match "(?i)cell|house|work"]
Field error in object 'app' on field 'adminContactNumber.value': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber.value,Pattern.adminContactNumber.value,Pattern.value,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.value,adminContactNumber.value]; arguments []; default message [adminContactNumber.value],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@19fc2c37]; default message [must match "\d{3}-\d{3}-\d{4}"]
Field error in object 'app' on field 'mainScreenProperties.width': rejected value [10]; codes [Min.app.mainScreenProperties.width,Min.mainScreenProperties.width,Min.width,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.mainScreenProperties.width,mainScreenProperties.width]; arguments []; default message [mainScreenProperties.width],50]; default message [must be greater than or equal to 50]
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:334)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:291)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization (AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:543)
at org.springframework.boot.SpringApplication.refresh (SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext (SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1107)
at com.logicbig.example.ExampleMain.main (ExampleMain.java:11)
Caused by: org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 3 errors
Field error in object 'app' on field 'adminContactNumber.type': rejected value [personal]; codes [Pattern.app.adminContactNumber.type,Pattern.adminContactNumber.type,Pattern.type,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.type,adminContactNumber.type]; arguments []; default message [adminContactNumber.type],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@7da4250d]; default message [must match "(?i)cell|house|work"]
Field error in object 'app' on field 'adminContactNumber.value': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber.value,Pattern.adminContactNumber.value,Pattern.value,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber.value,adminContactNumber.value]; arguments []; default message [adminContactNumber.value],[Ljavax.validation.constraints.Pattern$Flag;@3e6cd9d9,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@19fc2c37]; default message [must match "\d{3}-\d{3}-\d{4}"]
Field error in object 'app' on field 'mainScreenProperties.width': rejected value [10]; codes [Min.app.mainScreenProperties.width,Min.mainScreenProperties.width,Min.width,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.mainScreenProperties.width,mainScreenProperties.width]; arguments []; default message [mainScreenProperties.width],50]; default message [must be greater than or equal to 50]
at org.springframework.boot.bind.PropertiesConfigurationFactory.checkForBindingErrors (PropertiesConfigurationFactory.java:359)
at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget (PropertiesConfigurationFactory.java:276)
at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget (PropertiesConfigurationFactory.java:240)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:329)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:291)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization (AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:543)
at org.springframework.boot.SpringApplication.refresh (SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext (SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run (SpringApplication.java:1107)
at com.logicbig.example.ExampleMain.main (ExampleMain.java:11)

Example Project

Dependencies and Technologies Used:

  • Spring Boot 1.5.6.RELEASE
    Corresponding Spring Version 4.3.10.RELEASE
  • spring-boot-starter (Core starter, including auto-configuration support, logging and YAML)
  • hibernate-validator 5.3.5.Final (Hibernate's Bean Validation (JSR-303) reference implementation)
  • JDK 1.8
  • Maven 3.3.9

@ConfigurationProperties Cascaded Validation Example Select All Download
  • configuration-properties-nested-validation
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • MyAppProperties.java
          • resources

    See Also