Clarify confusing router vhost "default" vs "domains" config semantics
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 71
- Forks
- 111
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 110
Description
Description
The router.vhosts.main / router.vhosts.sandbox configuration (in gateway-helm-chart values → rendered into the controller's config.toml) has two fields — default and domains — whose behavior is very hard to reason about. The field names imply one thing but the code does another. This configuration surface was introduced in #403.
The core confusion: default reads like "the fallback hostname the vhost matches", but in the code it is really a bucket identifier (a routing key), and it is only matched as a Host when domains is empty. The moment domains is set, default is no longer matched against any request — domains becomes the sole Host-match list, and default silently degrades to a label.
Example config:
vhosts:
main:
domains: ["api.example.com"]
default: "foo.com"
sandbox:
domains: ["sandbox.api.example.com"]
default: "sandbox-foo.com"
With this, foo.com / sandbox-foo.com never match any request. Only api.example.com → main upstream and sandbox.api.example.com → sandbox upstream work. An operator who set default: "foo.com" will reasonably expect foo.com to be reachable, and it is not.
Second source of confusion — what is stored vs. what is live:
- The per-API vhost name is resolved to a concrete value at deploy time (
resolveVhostSentinels,gateway/gateway-controller/pkg/utils/api_deployment.go:308) and frozen into the DB (marshaled fromSourceConfiguration). domainsis not stored per-API — it is read live fromconfig.tomlat xDS translation time (getVHostDomains,gateway/gateway-controller/pkg/xds/translator.go:974-1013).
As a result, changing domains in config.toml behaves inconsistently depending on whether default is also changed:
- Change only
domains(keepdefault): existing APIs are silently re-hosted to the new domains after a restart. - Change
default: existing APIs stay pinned to their old frozen name and the newdomainsis ignored for them — it only applies to APIs deployed after the change.
This "freeze" is intentional, but it is undocumented and surprising, and the default/domains naming makes it nearly impossible to predict the Envoy VirtualHost.domains that will actually be produced.
Affected areas
kubernetes/helm/gateway-helm-chart/values.yaml(+templates/gateway/gateway-config.yaml:211-221)gateway/gateway-controller/pkg/config/config.go(VHostEntry,validateVHostsConfig)gateway/gateway-controller/pkg/xds/translator.go(getVHostDomains)gateway/gateway-controller/pkg/utils/api_deployment.go(resolveVhostSentinels)
Suggested improvements (pick/refine)
- Rename fields to reflect their real roles, e.g.
default→id/name(the bucket identity) and keepdomainsas the Host-match list; or collapse to a single clearer model. - If both are kept, document explicitly that
domainsoverridesdefaultfor Host matching, and thatdefaultis only matched whendomainsis empty. - Document the deploy-time freeze: the vhost name is persisted per-API, so changing
defaultdoes not re-route existing APIs, while changingdomains(with an unchangeddefault) does. - Consider a validation/warn when an API's explicit vhost equals one of the configured
domains(produces a duplicate-domain Envoy config that is rejected). - Add operator-facing docs with a worked example mapping config → resulting Envoy
VirtualHost.domains.
Version
No response
Related Issue
Introduced by #403
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with kubernetes/helm/gateway-helm-chart/values.yaml and templates/gateway/gateway-config.yaml:211-221, then trace VHostEntry and validateVHostsConfig in config.go. Read getVHostDomains in translator.go and resolveVhostSentinels in api_deployment.go to map deploy-time and live behavior. Done means the chosen field semantics, persistence behavior, and a config-to-Envoy example are documented, with any agreed validation or naming changes scoped clearly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, helm
- Domain
- api, backend-api-design, devops
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100