grpc/grpc-go · error
xdsclient: serverConfig is nil
Error message
xdsclient: serverConfig is nil
What it means
Inside `newXDSChannel` (channel.go:79), after the transport check, the next mandatory field is `serverConfig` (*ServerConfig) describing which xDS management server to connect to. The channel needs the server's ServerIdentifier (address, etc.) and features to dial the right destination, so a nil value is rejected at channel.go:83-84.
Source
Thrown at internal/xds/clients/xdsclient/channel.go:84
type xdsChannelOpts struct {
transport clients.Transport // Takes ownership of this transport.
serverConfig *ServerConfig // Configuration of the server to connect to.
clientConfig *Config // Complete xDS client configuration, used to decode resources.
eventHandler xdsChannelEventHandler // Callbacks for ADS stream events.
backoff func(int) time.Duration // Backoff function to use for stream retries. Defaults to exponential backoff, if unset.
watchExpiryTimeout time.Duration // Timeout for ADS resource watch expiry.
logPrefix string // Prefix to use for logging.
}
// newXDSChannel creates a new xdsChannel instance with the provided options.
// It performs basic validation on the provided options and initializes the
// xdsChannel with the necessary components.
func newXDSChannel(opts xdsChannelOpts) (*xdsChannel, error) {
switch {
case opts.transport == nil:
return nil, errors.New("xdsclient: transport is nil")
case opts.serverConfig == nil:
return nil, errors.New("xdsclient: serverConfig is nil")
case opts.clientConfig == nil:
return nil, errors.New("xdsclient: clientConfig is nil")
case opts.eventHandler == nil:
return nil, errors.New("xdsclient: eventHandler is nil")
}
xc := &xdsChannel{
transport: opts.transport,
serverConfig: opts.serverConfig,
clientConfig: opts.clientConfig,
eventHandler: opts.eventHandler,
closed: syncutil.NewEvent(),
}
l := grpclog.Component("xds")
logPrefix := opts.logPrefix + fmt.Sprintf("[xds-channel %p] ", xc)
xc.logger = igrpclog.NewPrefixLogger(l, logPrefix)
View on GitHub (pinned to 0c51461d27)
Solutions
- Verify the Config.Authorities and Config.Servers entries used to resolve the serverConfig are non-empty and well-formed.
- If you author a custom ResourceType or authority resolution path, ensure it always yields a non-nil *ServerConfig.
- Add a sanity check that logs the serverConfig before calling newXDSChannel so the source of the nil is obvious.
Example fix
// before
opts := xdsChannelOpts{transport: t, clientConfig: cc, eventHandler: h}
xc, err := newXDSChannel(opts) // err: serverConfig is nil
// after
sc, ok := resolveServerConfig(authorityName)
if !ok || sc == nil { return fmt.Errorf("no server config for authority %q", authorityName) }
opts := xdsChannelOpts{transport: t, serverConfig: sc, clientConfig: cc, eventHandler: h}
xc, err := newXDSChannel(opts) Defensive patterns
Strategy: validation
Validate before calling
func resolveAndValidateServerConfig(authorities map[string]xdsclient.Authority, authorityName string) (*xdsclient.ServerConfig, error) {
a, ok := authorities[authorityName]
if !ok {
return nil, fmt.Errorf("authority %q not configured", authorityName)
}
if len(a.XDSServers) == 0 || a.XDSServers[0].ServerIdentifier.ServerURI == "" {
return nil, fmt.Errorf("authority %q has no xDS servers", authorityName)
}
return &a.XDSServers[0], nil
} Prevention
- Validate the Config.Authorities and Config.Servers entries at construction time, not at channel-creation time.
- Refuse to start an authority that has no resolvable server config.
- Log the resolved ServerConfig before channel creation so the source of a nil is obvious.
When it happens
Trigger: Triggered when `newXDSChannel` is called with `opts.serverConfig == nil` while building a channel for an authority. This is an internal contract violation: the caller (the XDSClient) is expected to resolve a server config before requesting a channel.
Common situations: An xDS authority/configuration that resolves to no servers (e.g. an authority name in the Config map but with empty XDSServers); a custom resource-type implementation that bypasses the normal resolution; misconstructed Config.Authorities map.
Related errors
- xdsclient: transport is nil
- xdsclient: clientConfig is nil
- xdsclient: eventHandler is nil
- xds_wrr_locality: invalid LBConfig: child policy field must
- lrsclient: transport builder is nil
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/0f12cb568aabd7cf.
Report an issue: GitHub.