There appears to be a mismatch between the documented Gateway API Listener/ListenerSet status model and the current gateway-api v1.5.1 ListenerSet conformance tests.
For ListenerSet listener conflicts, the docs and GEP examples indicate that the losing listener should report:
Conflicted=True with reason HostnameConflict or ProtocolConflict
Accepted=False with reason PortUnavailable
Programmed=False with reason PortUnavailable
However, the current v1.5.1 ListenerSet conformance tests expect:
Conflicted=True with reason HostnameConflict or ProtocolConflict
Accepted=False with reason HostnameConflict or ProtocolConflict
Programmed=False with reason HostnameConflict or ProtocolConflict
This creates an ambiguity for implementations; following the published docs/examples can fail current conformance.
Findings
1. Gateway API reason definitions suggest HostnameConflict / ProtocolConflict are Conflicted reasons
ListenerReasonHostnameConflict is documented as:
- used with the
Conflicted condition when the listener conflicts with hostnames in other listeners
ListenerReasonProtocolConflict is documented as:
- used with the
Conflicted condition when listeners share a port but have conflicting protocols
2. Gateway API reason definitions suggest PortUnavailable is the preferred Accepted=False loser reason
This matches the idea that the loser in a merged-listener conflict is not accepted because the effective port slot is unavailable.
3. GEP-1713 conflict examples use PortUnavailable for Accepted=False and Programmed=False
In GEP-1713 Conformance Details, the ListenerSet conflict examples show the conflicted listener using:
Accepted=False, reason PortUnavailable
Programmed=False, reason PortUnavailable
Conflicted=True, reason HostnameConflict or ProtocolConflict
This appears in both:
- ListenerSet protocol conflict examples
- ListenerSet hostname conflict examples
4. Current v1.5.1 ListenerSet conformance tests expect the conflict-specific reason on all three listener conditions
Current upstream tests appear to assert:
For hostname conflict:
Accepted=False, reason HostnameConflict
Programmed=False, reason HostnameConflict
Conflicted=True, reason HostnameConflict
For protocol conflict:
Accepted=False, reason ProtocolConflict
Programmed=False, reason ProtocolConflict
Conflicted=True, reason ProtocolConflict
Relevant tests:
conformance/tests/listenerset-hostname-conflict.go
conformance/tests/listenerset-protocol-conflict.go
Why this is a problem
This creates two competing sources of truth:
- API reason constant comments and GEP-1713 examples
- Current upstream ListenerSet conformance tests
An implementation that follows the published docs/examples can fail conformance.
An implementation that follows current conformance may end up with a reason taxonomy that is harder to justify from the API definitions.
Recommendation
I think the cleaner and better-documented behavior is:
Conflicted=True -> HostnameConflict / ProtocolConflict
Accepted=False -> PortUnavailable
Programmed=False -> PortUnavailable for these ListenerSet conflict cases, following GEP-1713’s examples
Expected outcome
A single authoritative status mapping for ListenerSet conflict cases so implementations do not have to choose between:
- following the docs/GEP examples, or
- passing the current upstream conformance tests
There appears to be a mismatch between the documented Gateway API Listener/ListenerSet status model and the current
gateway-apiv1.5.1 ListenerSet conformance tests.For ListenerSet listener conflicts, the docs and GEP examples indicate that the losing listener should report:
Conflicted=Truewith reasonHostnameConflictorProtocolConflictAccepted=Falsewith reasonPortUnavailableProgrammed=Falsewith reasonPortUnavailableHowever, the current v1.5.1 ListenerSet conformance tests expect:
Conflicted=Truewith reasonHostnameConflictorProtocolConflictAccepted=Falsewith reasonHostnameConflictorProtocolConflictProgrammed=Falsewith reasonHostnameConflictorProtocolConflictThis creates an ambiguity for implementations; following the published docs/examples can fail current conformance.
Findings
1. Gateway API reason definitions suggest
HostnameConflict/ProtocolConflictareConflictedreasonsListenerReasonHostnameConflictis documented as:Conflictedcondition when the listener conflicts with hostnames in other listenersListenerReasonProtocolConflictis documented as:Conflictedcondition when listeners share a port but have conflicting protocols2. Gateway API reason definitions suggest
PortUnavailableis the preferredAccepted=Falseloser reasonListenerConditionAcceptedlists preferredFalsereasons including:PortUnavailableUnsupportedProtocolNoValidCACertificateUnsupportedValueListenerReasonPortUnavailableis documented as:Acceptedcondition when the listener requests a port that cannot be used on the GatewayThis matches the idea that the loser in a merged-listener conflict is not accepted because the effective port slot is unavailable.
3. GEP-1713 conflict examples use
PortUnavailableforAccepted=FalseandProgrammed=FalseIn GEP-1713 Conformance Details, the ListenerSet conflict examples show the conflicted listener using:
Accepted=False, reasonPortUnavailableProgrammed=False, reasonPortUnavailableConflicted=True, reasonHostnameConflictorProtocolConflictThis appears in both:
4. Current v1.5.1 ListenerSet conformance tests expect the conflict-specific reason on all three listener conditions
Current upstream tests appear to assert:
For hostname conflict:
Accepted=False, reasonHostnameConflictProgrammed=False, reasonHostnameConflictConflicted=True, reasonHostnameConflictFor protocol conflict:
Accepted=False, reasonProtocolConflictProgrammed=False, reasonProtocolConflictConflicted=True, reasonProtocolConflictRelevant tests:
conformance/tests/listenerset-hostname-conflict.goconformance/tests/listenerset-protocol-conflict.goWhy this is a problem
This creates two competing sources of truth:
An implementation that follows the published docs/examples can fail conformance.
An implementation that follows current conformance may end up with a reason taxonomy that is harder to justify from the API definitions.
Recommendation
I think the cleaner and better-documented behavior is:
Conflicted=True->HostnameConflict/ProtocolConflictAccepted=False->PortUnavailableProgrammed=False->PortUnavailablefor these ListenerSet conflict cases, following GEP-1713’s examplesExpected outcome
A single authoritative status mapping for ListenerSet conflict cases so implementations do not have to choose between: