fix(proxy): build trace-collector identity from trust domain, not cluster domain#15404
Merged
Merged
Conversation
…ster domain LINKERD2_PROXY_TRACE_COLLECTOR_SVC_NAME was built from .Values.clusterDomain, while every other proxy identity (identity/destination/policy) uses the trust domain helper ($trustDomain = identityTrustDomain | default clusterDomain). On installs where identityTrustDomain differs from clusterDomain, the proxy pins a collector identity the meshed collector never presents, so the trace export mTLS handshake fails (received corrupt message of type InvalidContentType) and no proxy-native spans are delivered. App-SDK OTLP is unaffected, which masks the cause. Use $trustDomain to match the sibling identities. No behavior change when identityTrustDomain is unset (falls back to clusterDomain, byte-identical render). Only the pinned identity changes; the collector's DNS address still uses clusterDomain. Signed-off-by: Joe <joe@buoyant.io>
adleong
approved these changes
Jun 24, 2026
adleong
left a comment
Member
There was a problem hiding this comment.
Nice catch! thanks for the fix
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.
What / why
When proxy-native tracing is enabled, the proxy exports spans to the trace collector over mesh mTLS and pins the identity it expects the collector to present, via
LINKERD2_PROXY_TRACE_COLLECTOR_SVC_NAME. That value is built from.Values.clusterDomain, but a meshed collector - like every meshed workload - presents an identity suffixed with the trust domain.On a default install these are the same string (
cluster.local), so the bug is invisible. On any install whereidentityTrustDomain!=clusterDomain, the proxy demands a SAN the collector never presents, the trace-export handshake fails (received corrupt message of type InvalidContentTypeon the sender;unspecific protocol erroron the collector's inbound proxy), and no proxy-native spans are delivered. App-level SDK tracing to the collector is unaffected (it uses normal identity), which masks the cause.Root cause
charts/partials/templates/_proxy.tpldefines the helper used by every identity:The component identities (
IDENTITY/DESTINATION/POLICY) all use$trustDomain, but the trace-collector identity is the lone exception - it uses.Values.clusterDomain. This is the identity the connecting proxy pins, so it must use the trust domain like the others. (The separate..._SVC_ADDRline is the DNS address and correctly keeps usingclusterDomain.)The fix
One token: the trace-collector identity now uses
$trustDomain(already in scope) instead of.Values.clusterDomain.Scope / safety
identityTrustDomainis unset,$trustDomainfalls back to.Values.clusterDomain, so the render is byte-identical to today. Only installs with a custom, different trust domain change - for them, from broken to working.helm templatethat the collector's network address (...svc.<clusterDomain>) is untouched; only the pinned identity moves to the trust domain.Test plan
Render (
helm template,clusterDomain=mesh-dns,identityTrustDomain=my.trust):...serviceaccount.identity.linkerd.mesh-dns...svc.mesh-dns:4317...serviceaccount.identity.linkerd.my.trust...svc.mesh-dns:4317(unchanged)Live mTLS repro (k3d,
clusterDomain!=identityTrustDomain, meshed otel-collector):InvalidContentType; collector receives 0linkerd-proxyspans while an app-SDK OTLP control keeps delivering spans.InvalidContentTypestops;linkerd-proxyspans arrive. Toggled off and on (and back) plus negative/positive controls isolate the identity name as the sole cause.Note for maintainers - data plane needs a rebuilt image
This partial renders both control-plane component proxies (fixed at
helm upgrade) and data-plane sidecars - but the latter are stamped from the template baked into the proxy-injector image. So the chart change fixes control-plane proxies; application sidecars pick up the fix only once a proxy-injector image is built from this commit and rolled out. Worth a release-note callout. Until then, operators can work around per-workload viaproxy.additionalEnvoverridingLINKERD2_PROXY_TRACE_COLLECTOR_SVC_NAME(duplicate env, last-wins).