grpc/grpc-go · error
xdsclient: transport builder is nil
Error message
xdsclient: transport builder is nil
What it means
`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.
Source
Thrown at internal/xds/clients/xdsclient/xdsclient.go:108
// to these channels based on server configs within the authority config.
// The XDSClient maintains a list of interested authorities for each of
// these channels, and forwards updates from the channels to each of these
// authorities.
//
// Once all references to a channel are dropped, the channel is closed.
channelsMu sync.Mutex
xdsActiveChannels map[ServerConfig]*channelState // Map from server config to in-use xdsChannels.
metricsCleanup func()
}
// New returns a new xDS Client configured with the provided config.
func New(config Config) (*XDSClient, error) {
switch {
case config.ResourceTypes == nil:
return nil, errors.New("xdsclient: resource types map is nil")
case config.TransportBuilder == nil:
return nil, errors.New("xdsclient: transport builder is nil")
case config.Authorities == nil && config.Servers == nil:
return nil, errors.New("xdsclient: no servers or authorities specified")
}
if config.WatchExpiryTimeout == 0 {
config.WatchExpiryTimeout = defaultWatchExpiryTimeout
}
client, err := newClient(&config, name)
if err != nil {
return nil, err
}
// Register this client instance as an Async Reporter.
if client.metricsReporter != nil {
reporter := &xdsClientMetricReporter{c: client}
client.metricsCleanup = client.metricsReporter.RegisterAsyncReporter(reporter)
}
return client, nil
}
View on GitHub (pinned to 0c51461d27)
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.
Example fix
// before
cfg := xdsclient.Config{Node: node, ResourceTypes: rts, Servers: servers}
client, err := xdsclient.New(cfg) // err: transport builder is nil
// after
tb, err := clients.NewTransportBuilder(transportOpts)
if err != nil { return err }
cfg := xdsclient.Config{Node: node, ResourceTypes: rts, Servers: servers, TransportBuilder: tb}
client, err := xdsclient.New(cfg) Defensive patterns
Strategy: validation
Validate before calling
func newXDSClientWithBuilder(node clients.Node, tb clients.TransportBuilder, rts map[string]xdsclient.ResourceType, servers []xdsclient.ServerConfig) (*xdsclient.XDSClient, error) {
if tb == nil {
return nil, errors.New("a non-nil TransportBuilder is required")
}
return xdsclient.New(xdsclient.Config{Node: node, TransportBuilder: tb, ResourceTypes: rts, Servers: servers})
} Prevention
- 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.
When it happens
Trigger: Triggered by `xdsclient.New(config)` with `config.TransportBuilder == nil`. Validation runs before any authority/channel is created.
Common situations: 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.
Related errors
- xdsclient: resource types map is nil
- xdsclient: no servers or authorities specified
- xds_wrr_locality: invalid LBConfig: child policy field must
- lrsclient: transport builder is nil
- xdsclient: transport is nil
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/27930e774c40d469.
Report an issue: GitHub.