fix: route Hostname/ServiceEntry backendRefs to the requested port on multi-port hosts#14212
Merged
ymesika merged 4 commits intoJun 9, 2026
Conversation
… multi-port hosts Signed-off-by: Yossi Mesika <[email protected]>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes incorrect backend resolution when an HTTPRoute backendRef of kind: Hostname or kind: ServiceEntry specifies a port against a multi-port ServiceEntry host. The root cause was backendKey key-string serialization dropping the port, collapsing all ports into the same KRT index bucket and allowing the wrong cluster to be chosen at runtime.
Changes:
- Add a
backendKey.String()implementation that includes the port to ensure per-port index bucketing. - Add new serviceentry/destination-rule golden test coverage for a multi-port
ServiceEntryreferenced viaHostnamebackendRef with an explicit port. - Add/record expected output demonstrating routing to the correct
..._80cluster (instead of incorrectly selecting..._443).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| pkg/krtcollections/policy.go | Adds backendKey.String() that includes port to prevent index key collisions across ports. |
| pkg/kgateway/setup/testdata/serviceentry/dr/se-hostname-ref-multiport.yaml | New test input: multi-port ServiceEntry with HTTPRoute referencing host via Hostname backendRef on port 80. |
| pkg/kgateway/setup/testdata/serviceentry/dr/se-hostname-ref-multiport-out.yaml | New golden output verifying the route cluster resolves to the ..._80 ServiceEntry cluster. |
davidjumani
approved these changes
Jun 9, 2026
davidjumani
enabled auto-merge
June 9, 2026 13:55
puertomontt
reviewed
Jun 9, 2026
Co-authored-by: Omar Hammami <[email protected]> Signed-off-by: Yossi Mesika <[email protected]>
Signed-off-by: Yossi Mesika <[email protected]>
puertomontt
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
An HTTPRoute
backendRefofkind: Hostnameorkind: ServiceEntrywith an explicitportcould route to the wrong port's cluster when the target ServiceEntry defines multiple ports for the same host.Example: a ServiceEntry exposing both
:80and:443onse.example.com, with an HTTPRoute backendRef ofport: 80, routes to the..._443cluster instead of..._80. The route showsAccepted/ResolvedRefs, so it only fails at runtime as wrong upstream routing (e.g.400 Client sent an HTTP request to an HTTPS server, or503against an HTTP-only backend).Root cause
ServiceEntry backends are aliased into the
BackendIndexkeyed bybackendKey, which embedsir.ObjectSourceplus aport. The KRT index serializes keys viafmt.Stringer, butbackendKeyhad noString()of its own — so the embeddedir.ObjectSource.String()was promoted, and that only encodesgroup/kind/namespace/name, dropping the port.Every port of a multi-port host therefore hashed to the same bucket. A lookup for
:80returned all ports' backends, and theResourceName()tiebreak picked:443(...:443_...sorts before...:80_...since"4" < "8") regardless of the requested port.The Fix
Give
backendKeyaString()that includes the port, so each (source, port) gets its own bucket.Applies to both
kind: Hostnameandkind: ServiceEntrybackendRefs.Change Type
/kind fix
Changelog
Additional Notes