skip to content

When properties come from both the Config Server and the client's local application.yml, which wins, and how can you change that?

level: seniorimportance: should knowfreq 58%

answer

  1. Default: remote overrides local
  2. override-none=true -> remote becomes fallback
  3. allow-override master switch (default true)
  4. override-system-properties default true
  5. import/uri/name must stay local (bootstrap paradox)

basics

~10 s

By 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 s

The 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 lines
yaml
spring:
  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

for a junior

Know that by default the Config Server's values override the client's local application.yml.

for a middle

Name the override-none flag and its effect (remote becomes fallback).

for a senior

Explain all three override flags and which config must stay local, plus how to inspect precedence via /actuator/env.

for a principal

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)

context