{"record":{"id":"27930e774c40d469","repo":"grpc/grpc-go","slug":"xdsclient-transport-builder-is-nil","errorCode":null,"errorMessage":"xdsclient: transport builder is nil","messagePattern":"xdsclient: transport builder is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/xdsclient/xdsclient.go","lineNumber":108,"sourceCode":"\t// to these channels based on server configs within the authority config.\n\t// The XDSClient maintains a list of interested authorities for each of\n\t// these channels, and forwards updates from the channels to each of these\n\t// authorities.\n\t//\n\t// Once all references to a channel are dropped, the channel is closed.\n\tchannelsMu        sync.Mutex\n\txdsActiveChannels map[ServerConfig]*channelState // Map from server config to in-use xdsChannels.\n\n\tmetricsCleanup func()\n}\n\n// New returns a new xDS Client configured with the provided config.\nfunc New(config Config) (*XDSClient, error) {\n\tswitch {\n\tcase config.ResourceTypes == nil:\n\t\treturn nil, errors.New(\"xdsclient: resource types map is nil\")\n\tcase config.TransportBuilder == nil:\n\t\treturn nil, errors.New(\"xdsclient: transport builder is nil\")\n\tcase config.Authorities == nil && config.Servers == nil:\n\t\treturn nil, errors.New(\"xdsclient: no servers or authorities specified\")\n\t}\n\tif config.WatchExpiryTimeout == 0 {\n\t\tconfig.WatchExpiryTimeout = defaultWatchExpiryTimeout\n\t}\n\tclient, err := newClient(&config, name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Register this client instance as an Async Reporter.\n\tif client.metricsReporter != nil {\n\t\treporter := &xdsClientMetricReporter{c: client}\n\t\tclient.metricsCleanup = client.metricsReporter.RegisterAsyncReporter(reporter)\n\t}\n\treturn client, nil\n}\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/xdsclient/xdsclient.go#L90-L126","documentation":"`xdsclient.New` (xdsclient.go:103) requires a non-nil `TransportBuilder` in Config — this is the component the client uses to create transports to each xDS management server. Without it, no ADS stream can ever be opened, so it is rejected at xdsclient.go:107-108.","triggerScenarios":"Triggered by `xdsclient.New(config)` with `config.TransportBuilder == nil`. Validation runs before any authority/channel is created.","commonSituations":"Constructing a Config without initializing the TransportBuilder; an earlier setup step (e.g. dialing a bootstrap-provided transport builder factory) failing silently; copying a Config struct that someone cleared.","solutions":["Set Config.TransportBuilder to a valid clients.TransportBuilder before calling xdsclient.New.","Verify the builder-creation step succeeded (capture its error) before assembling Config.","Build a Config factory that returns an error if TransportBuilder is nil, rather than relying on xdsclient.New to detect it."],"exampleFix":"// before\ncfg := xdsclient.Config{Node: node, ResourceTypes: rts, Servers: servers}\nclient, err := xdsclient.New(cfg) // err: transport builder is nil\n\n// after\ntb, err := clients.NewTransportBuilder(transportOpts)\nif err != nil { return err }\ncfg := xdsclient.Config{Node: node, ResourceTypes: rts, Servers: servers, TransportBuilder: tb}\nclient, err := xdsclient.New(cfg)","handlingStrategy":"validation","validationCode":"func newXDSClientWithBuilder(node clients.Node, tb clients.TransportBuilder, rts map[string]xdsclient.ResourceType, servers []xdsclient.ServerConfig) (*xdsclient.XDSClient, error) {\n    if tb == nil {\n        return nil, errors.New(\"a non-nil TransportBuilder is required\")\n    }\n    return xdsclient.New(xdsclient.Config{Node: node, TransportBuilder: tb, ResourceTypes: rts, Servers: servers})\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make TransportBuilder a required parameter of your Config factory.","Capture and check the error from builder creation before assembling Config.","Write a unit test that asserts a nil builder yields a clear error at your seam."],"tags":["grpc","xds","xdsclient","config-validation","transport"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}