{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/xdsclient/xdsresource/unmarshal_lds.go#L336-L372","documentation":"Returned when unmarshalling a filter chain's DownstreamTlsContext (unmarshal_lds.go:353-354) if the typed config parses but its common_tls_context field is nil. The server-side security handler needs a CommonTlsContext to build the downstream (server) TLS config; a DownstreamTlsContext with only require_client_certificate or session fields but no common_tls_context is rejected.","triggerScenarios":"An LDS filter chain provides a transport_socket with typed_config DownstreamTlsContext whose common_tls_context is unset. After proto.Unmarshal, the nil check at line 353 fires and the filter chain is rejected.","commonSituations":"Control plane sends a partial DownstreamTlsContext (e.g. only require_client_certificate set); templating bug; a fixture missing the TLS context body.","solutions":["Populate DownstreamTlsContext.common_tls_context with identity (and root, if mTLS) certificate provider config.","If TLS is not intended for that filter chain, remove the transport_socket so no DownstreamTlsContext is parsed.","Inspect the raw listener/filter-chain resource and confirm common_tls_context is present."],"exampleFix":"// before\n//   downstream_tls_context: { require_client_certificate: true }  // no common_tls_context\n// after\n//   downstream_tls_context: {\n//     common_tls_context: { tls_certificate_certificate_provider_instance: {...}, validation_context: {...} },\n//     require_client_certificate: true\n//   }","handlingStrategy":"validation","validationCode":"func downstreamTLSHasCommonCtx(dts *v3tlspb.DownstreamTlsContext) bool {\n    return dts != nil && dts.GetCommonTlsContext() != nil\n}","typeGuard":"func isCompleteDownstreamTLS(dts *v3tlspb.DownstreamTlsContext) bool {\n    return downstreamTLSHasCommonCtx(dts)\n}","tryCatchPattern":null,"preventionTips":["Always populate common_tls_context in DownstreamTlsContext for gRPC.","If TLS is not needed, remove the transport_socket from the filter chain.","Validate listener security fixtures in tests before publishing."],"tags":["xds","lds","tls","mtls","security","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}