I'm using a property file read by a class with @ConfigurationProperties and @Validated. It appears that missing environment variables are passed on as the literal string value from the properties file, instead of getting an error or the default. Ran into this with spring-boot 1.5.3.

Example:
application-default.properties test.demo=${MISSING_ENV}

TestConfig.java

@Configuration
@EnableConfigurationProperties({TestProperties.class})
public class TestConfig {
    public TestConfig(TestProperties test) {
        System.out.println("Test: "+test.getDemo());
    }

TestProperties.java

@ConfigurationProperties(prefix = "test")
@Validated
public class TestProperties {
    @NotNull
    private String demo = "this is my default";

    public String getDemo() {
        return demo;
    }

    public void setDemo(String demo) {
        this.demo = demo;
    }
}

Output on startup is:
Test: ${MISSING_ENV}

If I define MISSING_ENV first to be "here now", output is:
Test: here now

I can define a default in the application-default.properties file, but I don't want to do that for things like application secrets. Failure on startup with with a nice configuration report is what I'm hoping for here.

Bonus: If the property is an int instead of a String, startup fails but contains non-helpful detail:

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

Description:

Binding to target foo.TestProperties@3068b369 failed:

    Property: test.demo
    Value: ${MISSING_ENV}
    Reason: Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'demo'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [@javax.validation.constraints.NotNull int]


Action:

Update your application's configuration

Comment From: wilkinsona

Duplicates #8693

Comment From: elwaxoro

Appreciate the fast response! Disappointed to have to wait till December(?) for the 2.0 release, but at least it's already in hand.

Comment From: wilkinsona

Sorry about the wait, but it's a breaking change so it needs to wait for 2.0.

Comment From: elwaxoro

For anyone coming after, I found a partial workaround for this. Unfortunately, it doesn't allow defaults in the @ConfigurationProperties file, but it can catch missing environment variables:

    @NotNull
    @Pattern(regexp = "^(?!(\\$\\{.+\\})$).+$", message="Environment variable is missing")
    private String demo;

This prevents strings of the style ${ENV_VAR} from getting through. ${ENV_VAR:default} still shows up correctly as "default".

Comment From: gbzarelli

For anyone coming after, I found a partial workaround for this. Unfortunately, it doesn't allow defaults in the @ConfigurationProperties file, but it can catch missing environment variables:

java @NotNull @Pattern(regexp = "^(?!(\\$\\{.+\\})$).+$", message="Environment variable is missing") private String demo;

This prevents strings of the style ${ENV_VAR} from getting through. ${ENV_VAR:default} still shows up correctly as "default".

Follow my solution: I create my own CheckEnvironment annotation, based in your pattern

https://gist.github.com/gbzarelli/72b5f9fb1a8a12939f4b378dcfae915c