Using Spring Boot YAML to Externalize Configuration
Externalize Spring Boot settings with a hierarchical YAML file, bind them to typed classes, verify values at runtime, and avoid common pitfalls.
11 Jan 2026, 04:36 UTC

Why externalize configuration with YAML
Spring Boot allows you to keep all runtime settings in a single hierarchical YAML file. This separation means the code stays free of hard‑coded values, making the application easier to read, test, and adapt to different environments without recompilation.
Minimal configuration example
A typical application.yml file can contain server, datasource, and any custom properties. The file is parsed as a tree, so indentation defines the property hierarchy.
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: myuser
password: secret
You can also create profile‑specific files such as application-dev.yml to override values for development, testing, or production.
Binding the YAML to a typed class
Define a configuration properties class and annotate it with @ConfigurationProperties. Spring Boot automatically maps the nested keys to the corresponding fields.
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceConfig {
private String url;
private String username;
private String password;
// getters and setters omitted for brevity
}
Enable the binding by adding @EnableConfigurationProperties on a configuration class, or let Spring Boot discover the class on the classpath.
How Spring Boot reads the YAML
The YAML file is loaded at startup and each key becomes a property whose path mirrors its indentation level. For example, server.port maps to the property server.port. The spring.datasource.url property is bound to the url field of DataSourceConfig because the prefix spring.datasource matches the class annotation.
Property precedence follows the same rules as traditional .properties files: explicit command‑line arguments or environment variables take precedence over YAML values, which in turn take precedence over defaults.
Key limitations
- No compile‑time type safety – misspelled keys or wrong field types are only detected when the application starts.
- Complex expressions or external includes are not supported; values must be literals.
- Property precedence can be confusing when both YAML and .properties files are present, especially if the same key appears in both.
YAML does not support external includes or file references; all configuration must reside in the same file or be loaded explicitly by the application. This restriction keeps the configuration tree simple but prevents reuse of common settings across multiple files.
Common mistakes and how to avoid them
- Mixing tabs with spaces. YAML requires exactly two spaces per indentation level. Tabs cause a parsing error and the application fails to start.
- Defining duplicate keys in the same section. The later entry silently overrides the earlier one, leading to unexpected configuration values.
- Over‑nesting sections, which reduces readability. Keep the hierarchy shallow; for deep structures consider using maps or separate files.
- Embedding business logic or conditional statements in the YAML file. YAML is meant for data only; any computation should be handled in code.
Another frequent issue is using tabs for indentation; the parser throws a `MappingException` and the application fails to start, which can be confusing when the file looks correct in an editor that displays whitespace differently.
Verification steps
After starting the application, check the startup log for the effective port. It should match the server.port value defined in application.yml. You can also query the Actuator endpoint:
curl http://localhost:8080/actuator/env | grep server.port
Write a unit test that autowires the configuration class and asserts the bound fields:
@SpringBootTest
class ConfigTest {
@Autowired
private DataSourceConfig config;
@Test
void propertiesAreBound() {
assertEquals("jdbc:postgresql://localhost:5432/mydb", config.getUrl());
assertEquals("myuser", config.getUsername());
}
}
Alternatively, inject the Environment bean and verify the resolved property directly.
You can also enable debug logging for the environment to see the effective property values: set `logging.level.org.springframework.boot.context.properties=DEBUG` in the YAML file and observe the startup logs.
Version considerations
Spring Boot 2.5 introduced a more relaxed YAML parser, while Spring Boot 3.0 refined property precedence and deprecated certain legacy keys. Verify that your project’s Spring Boot version matches the documentation for the YAML features you use, especially if you rely on placeholder substitution or profile‑specific files.
Summary
Externalizing settings in a hierarchical YAML file reduces code clutter, improves maintainability, and lets teams manage configuration without touching source code. The mechanism relies on indentation‑based property paths and automatic binding via @ConfigurationProperties. Remember the limits — no compile‑time checks, no expressions — and avoid common pitfalls such as mixed whitespace, duplicate keys, and embedding logic. Verify the effective values at runtime and include a simple unit test to keep the configuration reliable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.