When properties come from both the Config Server and the client's local application.yml, which wins, and how can you change that?
answer
- Default: remote overrides local
- override-none=true -> remote becomes fallback
- allow-override master switch (default true)
- override-system-properties default true
- import/uri/name must stay local (bootstrap paradox)
basics
~10 sBy default the Config Server's properties take precedence over the client's local application.yml, so central config overrides local defaults. You can flip this with flags like spring.cloud.config.override-none=true so local values win instead.
solid answer
~40 sThe whole point of centralized config is that remote wins: by default property sources fetched from the Config Server are placed with higher precedence than the client's own application.properties/yml, so central values override local defaults. That behavior is tunable via spring.cloud.config.allow-override, override-none, and override-system-properties. Setting override-none=true (with allow-override=true) makes remote config lowest priority so it never overrides anything local — effectively 'remote as fallback.' override-system-properties (default true) controls whether remote can beat JVM/system properties. The local application.yml still owns the spring.config.import declaration and connection details (uri, name, profile) because those must be known before the fetch happens — you cannot fetch config to tell the client where to fetch config from.
code
yaml · 9 linesspring:
config:
import: "configserver:http://config:8888"
cloud:
config:
allow-override: true
override-none: true # remote becomes a FALLBACK; local wins
override-system-properties: false # env vars / JVM props beat the server
# With defaults (override-none omitted/false) the SERVER wins over local application.yml.go deeper
Know that by default the Config Server's values override the client's local application.yml.
Name the override-none flag and its effect (remote becomes fallback).
Explain all three override flags and which config must stay local, plus how to inspect precedence via /actuator/env.
Design an org-wide precedence policy (secrets from env beating central config, local-as-fallback for some teams) and audit ordering after a bootstrap-to-ConfigData migration.
## The default: remote overrides local The reason a Config Server exists is to be the **source of truth**. So by default, property sources returned by the server are inserted with **higher precedence** than the client's local `application.properties` / `application.yml`. If both define `logging.level.root`, the server's value wins. Local files act as **defaults/fallbacks** that centralized config can override per environment. ## What must stay local A few things logically **cannot** come from the server and therefore live in local `application.yml` (or env vars): - `spring.config.import=configserver:...` (the instruction to fetch at all) - `spring.cloud.config.uri`, `spring.application.name`, active profiles, `label` - `fail-fast` / `retry` settings These are needed to *perform* the fetch, so they're read before any remote source exists. (Bootstrapping paradox: you can't download the address you download from.) ## Tuning precedence — the three flags Spring Cloud Config exposes flags to change the default remote-wins behavior: - **`spring.cloud.config.allow-override`** (default true) — master switch; if false, the other override flags are locked at their defaults and users can't change precedence behavior. - **`spring.cloud.config.override-none`** (default false) — when true (and allow-override true), remote properties are given **lowest** priority: they fill in only what's not already set locally. This makes central config a *fallback* rather than an override. - **`spring.cloud.config.override-system-properties`** (default true) — whether remote should override **system properties** and environment variables. Set false so OS/JVM externalized config still beats the server. ## Typical intents - **Default (override-none=false):** central config is authoritative — standard for shared platform settings. - **override-none=true:** local wins; server only supplies values you didn't set — useful when teams want strong local control with central defaults. - **override-system-properties=false:** let container/orchestrator env vars (e.g., injected secrets) beat the server without editing central files. ## Multiple config-server sources If the server returns several property sources (e.g., `orders-prod.yml` and `orders.yml`), more-specific (profile-specific) sources win over generic ones — the server orders them, and the client preserves that order above local files (under default settings). ## Gotcha vs. legacy bootstrap Under the old bootstrap context the same override flags existed but were evaluated in the bootstrap phase. With the ConfigData `spring.config.import` mechanism the intent is the same (remote-wins by default) but the property sources are woven into Boot's standard Environment ordering. When migrating, verify that a property you *expected* local to win is behaving as intended — a subtle change in ordering can surprise you. ## Debugging precedence Hit `/actuator/env` (or enable `--debug` / conditions report) to see the exact ordered list of PropertySources and confirm which one supplied a given key. Never guess — inspect the actual `Environment` ordering.
- Why can't the spring.config.import / spring.cloud.config.uri themselves come from the Config Server?They are needed to know whether and where to fetch remote config, so they must be resolvable before any remote property source exists. It's a bootstrap paradox — you can't download the location you download from.
- You want an injected secret from an env var to beat a stale value in the Config Server. Which flag helps?spring.cloud.config.override-system-properties=false, so system properties and environment variables take precedence over the remote config.
saying these in an interview costs you the question
- Assuming local application.yml always wins over the Config Server by default
- Thinking you can move spring.config.import itself into server-side config
- Confusing override-none (lowers remote priority) with allow-override (the master enable switch)