{"record":{"id":"3f46f004e37fe999","repo":"grpc/grpc-go","slug":"unsupported-field-use-original-dst-is-present-an","errorCode":null,"errorMessage":"unsupported field 'use_original_dst' is present and set to true","messagePattern":"unsupported field 'use_original_dst' is present and set to true","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/xdsclient/xdsresource/unmarshal_lds.go","lineNumber":277,"sourceCode":"\t}\n\tvar i int\n\tfor ; i < len(ret)-1; i++ {\n\t\tif ret[i].Filter.IsTerminal() {\n\t\t\treturn nil, fmt.Errorf(\"http filter %q is a terminal filter but it is not last in the filter chain\", ret[i].Name)\n\t\t}\n\t}\n\tif !ret[i].Filter.IsTerminal() {\n\t\treturn nil, fmt.Errorf(\"http filter %q is not a terminal filter\", ret[len(ret)-1].Name)\n\t}\n\treturn ret, nil\n}\n\nfunc processServerSideListener(lis *v3listenerpb.Listener) (*ListenerUpdate, error) {\n\tif n := len(lis.ListenerFilters); n != 0 {\n\t\treturn nil, fmt.Errorf(\"unsupported field 'listener_filters' contains %d entries\", n)\n\t}\n\tif lis.GetUseOriginalDst().GetValue() {\n\t\treturn nil, errors.New(\"unsupported field 'use_original_dst' is present and set to true\")\n\t}\n\taddr := lis.GetAddress()\n\tif addr == nil {\n\t\treturn nil, fmt.Errorf(\"no address field in LDS response: %+v\", lis)\n\t}\n\tsockAddr := addr.GetSocketAddress()\n\tif sockAddr == nil {\n\t\treturn nil, fmt.Errorf(\"no socket_address field in LDS response: %+v\", lis)\n\t}\n\tlu := &ListenerUpdate{\n\t\tTCPListener: &InboundListenerConfig{\n\t\t\tAddress: sockAddr.GetAddress(),\n\t\t\tPort:    strconv.Itoa(int(sockAddr.GetPortValue())),\n\t\t},\n\t}\n\n\t// Populate the default filter chain.\n\tif dfc := lis.GetDefaultFilterChain(); dfc != nil {","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/xdsclient/xdsresource/unmarshal_lds.go#L259-L295","documentation":"Returned by processServerSideListener (unmarshal_lds.go:276-277) when the LDS Listener has use_original_dst set to true. gRPC's xDS server-side listener model does not implement original-destination-based routing (an Envoy feature), so the listener resource is rejected to avoid silently misrouting traffic. The check is an explicit guard early in server listener processing.","triggerScenarios":"An xDS server-side Listener resource with use_original_dst=true is received by the gRPC xDS client. processServerSideListener reads lis.GetUseOriginalDst().GetValue() and, on true, returns the error, NACKing the resource.","commonSituations":"Reusing an Envoy listener config verbatim that relies on original_dst; a control plane template that sets use_original_dst by default; porting a service-mesh listener to gRPC xDS.","solutions":["Set use_original_dst to false (or omit it) in the server-side Listener resource for gRPC xDS.","If original-destination routing is required, keep that logic in Envoy/sidecar rather than the gRPC xDS server listener.","Update the control-plane listener template to drop original_dst fields when targeting gRPC."],"exampleFix":"// before\n//   listener: { use_original_dst: true, ... }\n// after\n//   listener: { use_original_dst: false, ... }   // or omit the field","handlingStrategy":"validation","validationCode":"func listenerUsesNoOriginalDst(lis *v3listenerpb.Listener) error {\n    if lis.GetUseOriginalDst().GetValue() {\n        return errors.New(\"use_original_dst is unsupported by gRPC xDS\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not set use_original_dst on listeners served to gRPC xDS clients.","Keep original-destination routing in Envoy/sidecar, not the gRPC server listener.","Version your listener templates so gRPC-targeted ones strip Envoy-only fields."],"tags":["xds","lds","listener","config","server"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}