{"record":{"id":"1d62a49b5910c179","repo":"grpc/grpc-go","slug":"downstreamtlscontext-in-lds-response-does-not-cont","errorCode":null,"errorMessage":"DownstreamTlsContext in LDS response does not contain a CommonTlsContext","messagePattern":"DownstreamTlsContext in LDS response does not contain a CommonTlsContext","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/xdsclient/xdsresource/unmarshal_lds.go","lineNumber":354,"sourceCode":"\tif name := ts.GetName(); name != transportSocketName {\n\t\treturn emptyFilterChain, fmt.Errorf(\"transport_socket field has unexpected name: %s\", name)\n\t}\n\ttc := ts.GetTypedConfig()\n\tif typeURL := tc.GetTypeUrl(); typeURL != version.V3DownstreamTLSContextURL {\n\t\treturn emptyFilterChain, fmt.Errorf(\"transport_socket missing typed_config or wrong type_url: %q\", typeURL)\n\t}\n\tdownstreamCtx := &v3tlspb.DownstreamTlsContext{}\n\tif err := proto.Unmarshal(tc.GetValue(), downstreamCtx); err != nil {\n\t\treturn emptyFilterChain, fmt.Errorf(\"failed to unmarshal DownstreamTlsContext in LDS response: %v\", err)\n\t}\n\tif downstreamCtx.GetRequireSni().GetValue() {\n\t\treturn emptyFilterChain, fmt.Errorf(\"require_sni field set to true in DownstreamTlsContext message: %v\", downstreamCtx)\n\t}\n\tif downstreamCtx.GetOcspStaplePolicy() != v3tlspb.DownstreamTlsContext_LENIENT_STAPLING {\n\t\treturn emptyFilterChain, fmt.Errorf(\"ocsp_staple_policy field set to unsupported value in DownstreamTlsContext message: %v\", downstreamCtx)\n\t}\n\tif downstreamCtx.GetCommonTlsContext() == nil {\n\t\treturn emptyFilterChain, errors.New(\"DownstreamTlsContext in LDS response does not contain a CommonTlsContext\")\n\t}\n\tsc, err := securityConfigFromCommonTLSContext(downstreamCtx.GetCommonTlsContext(), true)\n\tif err != nil {\n\t\treturn emptyFilterChain, err\n\t}\n\tif sc != nil {\n\t\tsc.RequireClientCert = downstreamCtx.GetRequireClientCertificate().GetValue()\n\t\tif sc.RequireClientCert && sc.RootInstanceName == \"\" {\n\t\t\treturn emptyFilterChain, errors.New(\"security configuration on the server-side does not contain root certificate provider instance name, but require_client_cert field is set\")\n\t\t}\n\t\tfcc.SecurityCfg = sc\n\t}\n\treturn fcc, nil\n}\n\n// dstPrefixEntry wraps DestinationPrefixEntry to track build state.\ntype dstPrefixEntry struct {\n\tentry         DestinationPrefixEntry","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/xdsclient/xdsresource/unmarshal_lds.go#L336-L372","documentation":"Thrown when validating a DownstreamTlsContext attached to a server-side filter chain's transport socket: the typed_config parsed successfully into a DownstreamTlsContext message, but its common_tls_context field is nil. A DownstreamTlsContext without a CommonTlsContext has no certificate material to negotiate, so grpc-go rejects the filter chain.","triggerScenarios":"LDS FilterChain transport_socket typed_config is DownstreamTlsContext but the common_tls_context oneof/field is unset. Happens when a control plane emits a downstream TLS context skeleton (e.g. only setting require_client_certificate) but forgets the common_tls_context.","commonSituations":"Partial TLS config emitted during control-plane migration. Istio/equivalent resource where the server cert SDS reference is omitted. A user disabled TLS by removing common_tls_context but left the downstream_tls_context wrapper in place.","solutions":["Populate common_tls_context inside the DownstreamTlsContext (at minimum, an identity certificate provider).","If TLS is not intended, remove the transport_socket block from the filter chain entirely so grpc-go uses plaintext.","Validate the LDS resource with protoc and require common_tls_context != nil whenever DownstreamTlsContext is used."],"exampleFix":"// before\n//   transport_socket: { typed_config: { @type: \"...DownstreamTlsContext\", require_client_certificate: true } }\n// after\n//   transport_socket: { typed_config: {\n//     @type: \"...DownstreamTlsContext\",\n//     common_tls_context: { tls_certificate_provider_instance: { instance_name: \"default\" } }\n//   } }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"Handle in the LDS watcher callback. The error comes from filter-chain security parsing; log the listener name and the offending filter chain name (if available). The fix is in the control plane: either populate common_tls_context or remove the transport_socket.","preventionTips":["Policy-check LDS resources: any DownstreamTlsContext must carry a non-nil common_tls_context.","In your xDS server, refuse to serve a downstream TLS context without common_tls_context.","Integration-test server-side LDS resources end-to-end against grpc-go before rollout."],"tags":["xds","lds","tls","downstream-tls","config-validation","control-plane"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}