You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
api.xxx.xxx HTTPS and TLS conflicted in the tenant-root's TenantGateway cozystack listeners #3720
Describe the bug
When cozystack is freshly installed, the api.xxx.xxx HTTPS and TLS is conflicted in the tenant-root's TenantGateway cozystack listeners.
Causing the cilium-envoy refuses to accept and open for connection.
Environment
Cozystack version: v1.6.1
Provider: on-prem
To Reproduce
Steps to reproduce the behavior:
Freshly install cozystack v1.6.1
setup and configure the platform as documentation mentioned, but keep .spec.ingress: false in tenant-root
enable gateway on platform level and tenant level as documentation mentioned.
wait for all gateway related resources reconciled.
run telnet to test port 80 and 443
Expected behaviour
when running telnet to test the IP for connectivity, it should able to establish the connection.
Actual behaviour
the port 80 and 443 is never opened on the IP.
Logs
cilium-envoy's log.
repeating following warning.
cilium-envoy-qn4sg [2026-08-09 03:25:51.550[][7[][warning[][config[] [external/envoy/source/extensions/config_subscription/grpc/grpc_subscription_impl.cc:138] gRPC config for type.googleapis.com/envoy.config.listener.v3.Listener rejected: Error adding/updating listener(s) tenant-root/cilium-gateway-cozystack/listener: error adding listener '127.0.0.1:11652': filter chain '' has the same matching rules defined as ''. duplicate matcher is: {"transport_protocol":"tls","server_names":["api.xxx.xxx"]}
This is a known conflict between the wildcard HTTPS termination listener and the TLS passthrough listeners on port 443. Issue #3718 documents the same root cause [1].
What's happening: When using dns01 or existingSecret cert mode, the TenantGateway controller creates a wildcard HTTPS listener for *.<apex> on port 443 with tls.mode: Terminate[2]. At the same time, each entry in tlsPassthroughServices (by default: api, vm-exportproxy, cdi-uploadproxy) creates a TLS passthrough listener on port 443 with hostname <service>.<apex>[3][4]. Because the wildcard *.<apex> matches api.<apex>, both filter chains end up with an intersecting SNI match — and Cilium's Envoy translation on v1.19.5 produces two filter chains with identical transport_protocol: tls + server_names criteria, which Envoy rejects outright [1].
Root cause: This is a limitation of Cilium v1.19.5 (the version pinned in Cozystack). The listener translation builds a single Envoy listener for the entire Gateway and cannot isolate overlapping SNI matches between terminate and passthrough filter chains on the same port. The fix is targeted for Cilium 1.20, with no backport to 1.19 [5].
Possible workaround: If you're able to, you could try removing api from tlsPassthroughServices in the TenantGateway spec (if you don't need TLS passthrough for the Kubernetes API on this gateway), which would eliminate the overlapping SNI match and allow Envoy to accept the listener configuration. However, this would affect API server passthrough routing, so it depends on your setup.
This is essentially the same issue as #3718 — you've now confirmed with a live cluster and cilium-envoy logs what that issue predicted from code analysis alone.
Reproduced from the templates. This is deterministic on a default install with the Gateway enabled, not something specific to your cluster.
packages/system/cozystack-api/templates/api-tlsroute.yaml ships a TLSRoute named kubernetes-api in the default namespace with hostname api.<apex>, attaching by sectionName: tls-api. default sits in gateway.attachedNamespaces in the platform values, so collectHostnameClaims accepts that hostname as a claim. In http01, which is the default cert mode, the reconciler renders one HTTPS-terminate listener per claimed hostname and never subtracts the names already served by tlsPassthroughServices (internal/controller/tenantgateway/reconciler.go). That is how api.<apex> ends up with https-api-<hash> (HTTPS/Terminate) and tls-api (TLS/Passthrough) side by side on 443, exactly the pair in your listener dump.
On the pinned Cilium the whole Gateway translates into a single Envoy listener, so the conflicting pair takes 443 down with it. That is why neither 80 nor 443 ever opened.
Deleting the TLSRoute clears the claim and unblocks the listener, but the object is part of the cozystack-api chart, so Flux puts it back on the next reconcile, and while it is gone the tenant Kubernetes API is not published through the Gateway at all.
Same shape in dns01 is #3718, and #3342 is the change that stops rendering a terminate listener for passthrough names in http01.
Fixed on main by #3342: a hostname served by a passthrough listener no longer gets an HTTPS terminate listener too, so api.<apex> stops conflicting. It will ship in the next release after v1.6.3.
Activity
dosubot commentedon Aug 10, 2026
Hi Ray Low (@crossRT)! I'm Dosu and I'm helping the Cozystack team.
This is a known conflict between the wildcard HTTPS termination listener and the TLS passthrough listeners on port 443. Issue #3718 documents the same root cause [1].
What's happening: When using
dns01orexistingSecretcert mode, the TenantGateway controller creates a wildcard HTTPS listener for*.<apex>on port 443 withtls.mode: Terminate[2]. At the same time, each entry intlsPassthroughServices(by default:api,vm-exportproxy,cdi-uploadproxy) creates a TLS passthrough listener on port 443 with hostname<service>.<apex>[3] [4]. Because the wildcard*.<apex>matchesapi.<apex>, both filter chains end up with an intersecting SNI match — and Cilium's Envoy translation on v1.19.5 produces two filter chains with identicaltransport_protocol: tls+server_namescriteria, which Envoy rejects outright [1].Root cause: This is a limitation of Cilium v1.19.5 (the version pinned in Cozystack). The listener translation builds a single Envoy listener for the entire Gateway and cannot isolate overlapping SNI matches between terminate and passthrough filter chains on the same port. The fix is targeted for Cilium 1.20, with no backport to 1.19 [5].
Possible workaround: If you're able to, you could try removing
apifromtlsPassthroughServicesin the TenantGateway spec (if you don't need TLS passthrough for the Kubernetes API on this gateway), which would eliminate the overlapping SNI match and allow Envoy to accept the listener configuration. However, this would affect API server passthrough routing, so it depends on your setup.This is essentially the same issue as #3718 — you've now confirmed with a live cluster and cilium-envoy logs what that issue predicted from code analysis alone.
To reply, just mention @dosu.
Share context across your team and agents. Try Dosu.
lexfrei commentedon Aug 14, 2026
Reproduced from the templates. This is deterministic on a default install with the Gateway enabled, not something specific to your cluster.
packages/system/cozystack-api/templates/api-tlsroute.yamlships a TLSRoute namedkubernetes-apiin thedefaultnamespace with hostnameapi.<apex>, attaching bysectionName: tls-api.defaultsits ingateway.attachedNamespacesin the platform values, socollectHostnameClaimsaccepts that hostname as a claim. In http01, which is the default cert mode, the reconciler renders one HTTPS-terminate listener per claimed hostname and never subtracts the names already served bytlsPassthroughServices(internal/controller/tenantgateway/reconciler.go). That is howapi.<apex>ends up withhttps-api-<hash>(HTTPS/Terminate) andtls-api(TLS/Passthrough) side by side on 443, exactly the pair in your listener dump.On the pinned Cilium the whole Gateway translates into a single Envoy listener, so the conflicting pair takes 443 down with it. That is why neither 80 nor 443 ever opened.
Deleting the TLSRoute clears the claim and unblocks the listener, but the object is part of the cozystack-api chart, so Flux puts it back on the next reconcile, and while it is gone the tenant Kubernetes API is not published through the Gateway at all.
Same shape in dns01 is #3718, and #3342 is the change that stops rendering a terminate listener for passthrough names in http01.
lexfrei commentedon Sep 23, 2026
Fixed on main by #3342: a hostname served by a passthrough listener no longer gets an HTTPS terminate listener too, so
api.<apex>stops conflicting. It will ship in the next release after v1.6.3.