Description:
When a ListenerSet listener has a missing or unresolvable TLS certificate reference, Envoy Gateway sets the ListenerSet object-level Accepted condition to False. A Gateway in the identical situation remains Accepted: True. This is inconsistent and appears to contradict the Gateway API spec.
The spec defines the valid reasons for Accepted: False on a ListenerEntry (ListenerSet) and Listener (Gateway) — neither includes InvalidCertificateRef:
InvalidCertificateRef is explicitly placed under ResolvedRefs: False for both resource types:
The spec does include the escape hatch "Controllers may raise this condition with other reasons", but the placement of InvalidCertificateRef exclusively under ResolvedRefs makes the intent clear: a missing certificate is a reference resolution concern, not a structural validity concern. The listener configuration itself is valid.
Expected behavior: InvalidCertificateRef sets ResolvedRefs: False and Programmed: False at the listener level, with Accepted: True on the listener itself. The ListenerSet object-level Accepted condition also remains True, consistent with Gateway behavior.
Actual behavior: The listener-level Accepted condition is not set at all, and the ListenerSet object-level Accepted is set to False with reason ListenersNotValid — even though the equivalent Gateway scenario produces Accepted: True at both the listener and object level.
Real-world impact: This can create a bootstrapping deadlock any time a new ListenerSet references a certificate that does not yet exist. For users of tools such as external-dns that watch for Accepted: True before provisioning DNS records — without the DNS record, ACME HTTP-01 challenges cannot be completed, so the certificate is never issued and the ListenerSet remains Accepted: False.
Repro steps:
Apply the following manifests to a cluster running Envoy Gateway. Neither api-tls-gw nor api-tls-ls secrets exist.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway
namespace: envoy-gateway-system
spec:
gatewayClassName: eg
allowedListeners:
namespaces:
from: All
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: apigw.localhost
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: api-tls-gw
allowedRoutes:
namespaces:
from: All
apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
name: api
namespace: api
spec:
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway
namespace: envoy-gateway-system
listeners:
- name: api
port: 443
protocol: HTTPS
hostname: apils.localhost
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: api-tls-ls
allowedRoutes:
namespaces:
from: Same
Observe the Gateway conditions — Accepted: True despite the missing certificate:
status:
conditions:
- message: The Gateway has been scheduled by Envoy Gateway
reason: Accepted
status: "True"
type: Accepted
- message: Address assigned to the Gateway, 1/1 envoy replicas available
reason: Programmed
status: "True"
type: Programmed
listeners:
- conditions:
- message: 'No valid secrets exist: certificate refs 0: Secret envoy-gateway-system/api-tls-gw
does not exist.'
reason: InvalidCertificateRef
status: "False"
type: ResolvedRefs
- message: Listener is invalid, see other Conditions for details.
reason: Invalid
status: "False"
type: Programmed
name: https
Observe the ListenerSet conditions — Accepted: False for the same underlying cause:
status:
conditions:
- message: All listeners are invalid
reason: ListenersNotValid
status: "False"
type: Accepted
- message: All listeners are invalid
reason: ListenersNotValid
status: "False"
type: Programmed
listeners:
- conditions:
- message: 'No valid secrets exist: certificate refs 0: Secret api/api-tls-ls
does not exist.'
reason: InvalidCertificateRef
status: "False"
type: ResolvedRefs
- message: Listener is invalid, see other Conditions for details.
reason: ListenersNotValid
status: "False"
type: Programmed
name: api
Environment:
- Envoy Gateway version: >= v1.8.0-rc.0
- Kubernetes version: v1.35.0
- Gateway API version: v1.5.1
Description:
When a ListenerSet listener has a missing or unresolvable TLS certificate reference, Envoy Gateway sets the ListenerSet object-level
Acceptedcondition toFalse. A Gateway in the identical situation remainsAccepted: True. This is inconsistent and appears to contradict the Gateway API spec.The spec defines the valid reasons for
Accepted: Falseon a ListenerEntry (ListenerSet) and Listener (Gateway) — neither includesInvalidCertificateRef:Accepted: Falsereasons:PortUnavailable,UnsupportedProtocol,TooManyListenersAccepted: Falsereasons:PortUnavailable,UnsupportedProtocol,NoValidCACertificate,UnsupportedValueInvalidCertificateRefis explicitly placed underResolvedRefs: Falsefor both resource types:ResolvedRefs: FalsereasonsResolvedRefs: FalsereasonsThe spec does include the escape hatch "Controllers may raise this condition with other reasons", but the placement of
InvalidCertificateRefexclusively underResolvedRefsmakes the intent clear: a missing certificate is a reference resolution concern, not a structural validity concern. The listener configuration itself is valid.Expected behavior:
InvalidCertificateRefsetsResolvedRefs: FalseandProgrammed: Falseat the listener level, withAccepted: Trueon the listener itself. The ListenerSet object-levelAcceptedcondition also remainsTrue, consistent with Gateway behavior.Actual behavior: The listener-level
Acceptedcondition is not set at all, and the ListenerSet object-levelAcceptedis set toFalsewith reasonListenersNotValid— even though the equivalent Gateway scenario producesAccepted: Trueat both the listener and object level.Real-world impact: This can create a bootstrapping deadlock any time a new ListenerSet references a certificate that does not yet exist. For users of tools such as external-dns that watch for
Accepted: Truebefore provisioning DNS records — without the DNS record, ACME HTTP-01 challenges cannot be completed, so the certificate is never issued and the ListenerSet remainsAccepted: False.Repro steps:
Apply the following manifests to a cluster running Envoy Gateway. Neither
api-tls-gwnorapi-tls-lssecrets exist.Observe the Gateway conditions —
Accepted: Truedespite the missing certificate:Observe the ListenerSet conditions —
Accepted: Falsefor the same underlying cause:Environment: