Walk through how the Config Server resolves profiles and labels for a request, including precedence and the default label.
answer
- profile = which files + precedence; label = which git version
- {app}-{profile} > {app} > application-{profile} > application
- comma profiles: rightmost wins
- default-label main (was master) — classic mismatch bug
- escape slash as (_)
basics
~20 sProfiles pick which -{profile} files to include and how they layer (more specific wins over shared/base files). The label selects the git branch/tag/commit to read from; if the client sends none, the server's default-label (main, historically master) is used.
solid answer
~40 sTwo independent axes. Profile resolution: for /{app}/{profile}, the server gathers application.yml and application-{profile}.yml (shared) plus {app}.yml and {app}-{profile}.yml (app-specific), and orders the returned property sources most-specific-first — {app}-{profile} over {app} over application-{profile} over application. Multiple comma-separated profiles layer left-to-right with later profiles winning, enabling composite environments like dev,region-us. Label resolution: {label} selects the backend version — for git a branch, tag, or commit. If the client omits it, the git backend uses spring.cloud.config.server.git.default-label (main, formerly master). Slashes in a label are escaped as (_). The client can pin a label via spring.cloud.config.label. Profile affects which files and precedence; label affects which version of those files, and they combine so you can serve, say, orders-dev.yml from a release branch.
code
java · 26 lines// Server default label (used when client sends no {label}):
// spring:
// cloud:
// config:
// server:
// git:
// uri: https://github.com/acme/config-repo
// default-label: main # historically 'master' - a classic mismatch bug
// Client pins profile + label explicitly:
// spring:
// application:
// name: orders
// profiles:
// active: prod,region-eu # rightmost profile wins on conflicts
// cloud:
// config:
// label: release-2.4 # read from this git branch
// config:
// import: configserver:http://config:8888
// Effective request the client issues:
// GET /orders/prod,region-eu/release-2.4
// Resolves, on branch release-2.4, precedence high->low:
// orders-region-eu.yml > orders-prod.yml > orders.yml
// > application-region-eu.yml > application-prod.yml > application.ymlgo deeper
Know profile picks -{profile} files and label picks the git branch; default is main.
State the four file families and their precedence and that label maps to a git ref with a configurable default.
Explain multi-profile rightmost-wins layering, profile/label independence and combination, and the default-label mismatch bug.
Design branch-based config rollout strategies and multi-region profile composition, anticipating default-label and ordering failure modes across environments.
**Two orthogonal dimensions.** A request is `/{application}/{profile}/{label}`. Profile answers *which files and in what precedence*; label answers *which version of the repo those files come from*. They are resolved independently and then combined. **Profile resolution & precedence.** For `/{app}/{profile}` the server collects up to four families of files: 1. `application.{yml|properties}` — global defaults for every app. 2. `application-{profile}.{yml|properties}` — global per-profile defaults. 3. `{app}.{yml|properties}` — this app's base config. 4. `{app}-{profile}.{yml|properties}` — this app's per-profile config. The returned `propertySources` are ordered **most-specific-first**, roughly `{app}-{profile}` > `{app}` > `application-{profile}` > `application`. Because the client merges first-wins, the app+profile file overrides everything below it. Files that don't exist are simply skipped — not errors. **Multiple profiles.** `{profile}` may be comma-separated: `/{app}/dev,region-us`. Both profiles are active; their files are layered so that **later profiles in the list take precedence** over earlier ones. This composes cross-cutting slices (an environment profile plus a region profile) without duplicating files. YAML documents guarded by `spring.config.activate.on-profile` inside a single file are also honored. **Label resolution.** `{label}` is the backend version pointer: - **Git**: a branch, tag, or commit SHA. `JGitEnvironmentRepository` checks the repo out at that ref before reading. If the client sends no label, the server falls back to `spring.cloud.config.server.git.default-label` — `main` in current versions (historically `master`; misconfiguring this is a classic 'works locally, empty in CI' bug). - **Native**: label can map to a subdirectory of the search location, but there's no real version history. - Slashes must be escaped as `(_)` in the URL (e.g. `feature(_)x` for `feature/x`). - The client sets a label with `spring.cloud.config.label`; useful for canarying config on a branch before merging to main. **Combining them.** Profile and label are independent, so `/orders/prod/release-2.4` means: read the `release-2.4` git ref, then resolve `orders-prod.yml` + `orders.yml` + `application-prod.yml` + `application.yml` from *that* ref, ordered by precedence. This lets you stage a full config change on a branch and target it per-client. **Gotchas.** - Wrong `default-label` (repo uses `main`, server defaults to `master`) returns only defaults or an error → the classic empty-config symptom. - Property-source ordering is precedence: if you swap the intended override direction you'll silently get the wrong value. - Comma-separated profile order matters — the rightmost wins. - A label with a slash without `(_)` yields a 404/parse error. - Native backend labels don't give you git-style history. **When it matters.** Multi-environment, multi-region deployments and branch-based config rollouts all hinge on getting profile precedence and label selection right.
- A team switched their config repo's default branch to main but clients get empty config in one environment — likely cause?The Config Server's spring.cloud.config.server.git.default-label is still master (or clients request no label expecting master). The requested ref doesn't exist, so only defaults/nothing resolve. Set default-label: main or have clients send the right spring.cloud.config.label.
- In /orders/dev,region-us which profile's values win on a conflicting key?region-us — with comma-separated profiles the later (rightmost) profile takes precedence, layering over dev, both above the base application/orders files.
saying these in an interview costs you the question
- Believing later profiles are overridden by earlier ones (it's the reverse).
- Assuming the default label is always master.
- Treating profile and label as the same concept.