@@ -217,25 +217,11 @@ func validClientCertificateRef(ref *gwapiv1.SecretObjectReference) error {
217217func (t * Translator ) ProcessListeners (gateways []* GatewayContext , xdsIR resource.XdsIRMap , infraIR resource.InfraIRMap , resources * resource.Resources ) {
218218 // Infra IR proxy ports must be unique.
219219 foundPorts := make (map [string ][]* protocolPort )
220- t .validateConflictedLayer7Listeners (gateways )
221- t .validateConflictedLayer4Listeners (gateways , gwapiv1 .TCPProtocolType )
222- t .validateConflictedLayer4Listeners (gateways , gwapiv1 .UDPProtocolType )
223- if t .MergeGateways {
224- t .validateConflictedMergedListeners (gateways )
225- }
226220
227- // Iterate through all listeners to validate spec
228- // and compute status for each, and add valid ones
229- // to the Xds IR .
221+ // Phase 1: Validate each listener's spec independently.
222+ // This must happen before conflict resolution so that invalid listeners
223+ // don't block valid ones during conflict detection .
230224 for _ , gateway := range gateways {
231- irKey := t .getIRKey (gateway .Gateway )
232-
233- if gateway .envoyProxy != nil {
234- infraIR [irKey ].Proxy .Config = gateway .envoyProxy
235- }
236- t .processProxyReadyListener (xdsIR [irKey ], gateway .envoyProxy )
237- t .processProxyObservability (gateway , xdsIR [irKey ], infraIR [irKey ].Proxy , resources )
238-
239225 for _ , listener := range gateway .listeners {
240226 // Process protocol & supported kinds
241227 switch listener .Protocol {
@@ -277,9 +263,35 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR resource
277263
278264 // Process Hostname configuration
279265 t .validateHostName (listener )
266+ }
267+ }
280268
269+ // Phase 2: Run conflict detection.
270+ // Only listeners that haven't been marked as invalid will participate in conflict resolution.
271+ t .validateConflictedLayer7Listeners (gateways )
272+ t .validateConflictedLayer4Listeners (gateways , gwapiv1 .TCPProtocolType )
273+ t .validateConflictedLayer4Listeners (gateways , gwapiv1 .UDPProtocolType )
274+ if t .MergeGateways {
275+ t .validateConflictedMergedListeners (gateways )
276+ }
277+
278+ // Phase 3: Build IR for valid listeners.
279+ for _ , gateway := range gateways {
280+ irKey := t .getIRKey (gateway .Gateway )
281+
282+ if gateway .envoyProxy != nil {
283+ infraIR [irKey ].Proxy .Config = gateway .envoyProxy
284+ }
285+ t .processProxyReadyListener (xdsIR [irKey ], gateway .envoyProxy )
286+ t .processProxyObservability (gateway , xdsIR [irKey ], infraIR [irKey ].Proxy , resources )
287+
288+ for _ , listener := range gateway .listeners {
281289 // Process conditions and check if the listener is ready
282- t .validateListenerConditions (listener )
290+ isReady := t .validateListenerConditions (listener )
291+ if ! isReady {
292+ // Skip invalid listeners from IR building
293+ continue
294+ }
283295
284296 // Skip listeners with invalid frontend TLS validation as they are not functional.
285297 if listener .frontendTLSValidationInvalid () {
0 commit comments