{"record":{"id":"7c817b8ecb252cdf","repo":"grpc/grpc-go","slug":"xdsclient-no-servers-or-authorities-specified","errorCode":null,"errorMessage":"xdsclient: no servers or authorities specified","messagePattern":"xdsclient: no servers or authorities specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/xdsclient/xdsclient.go","lineNumber":110,"sourceCode":"\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\n// newClient returns a new XDSClient with the given config.\nfunc newClient(config *Config, target string) (*XDSClient, error) {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/xdsclient/xdsclient.go#L92-L128","documentation":"`xdsclient.New` (xdsclient.go:103) requires the caller to specify at least one xDS server: either Config.Servers (the top-level management servers) or Config.Authorities (per-authority server lists). If both are nil the client would have nowhere to connect, so xdsclient.go:109-110 returns this error.","triggerScenarios":"Triggered by `xdsclient.New(config)` where both `config.Servers == nil` and `config.Authorities == nil`. The check at line 109 short-circuits: the OR condition is only satisfied if at least one is non-nil.","commonSituations":"Loading a bootstrap that contains no server entries; mis-parsing the bootstrap so the server list ends up empty; building a Config in tests with only Node/TransportBuilder set; an authority map that exists but is empty in a way that decodes to nil.","solutions":["Populate Config.Servers with at least one ServerConfig, OR populate Config.Authorities with at least one named authority that itself has XDSServers.","If you are loading from a bootstrap file, validate that the file contains an `xds_servers` (or `authorities`) section before constructing Config.","Fail fast in your Config factory with a clearer error if both fields are empty."],"exampleFix":"// before\ncfg := xdsclient.Config{Node: node, TransportBuilder: tb, ResourceTypes: rts}\nclient, err := xdsclient.New(cfg) // err: no servers or authorities specified\n\n// after\ncfg := xdsclient.Config{\n    Node: node, TransportBuilder: tb, ResourceTypes: rts,\n    Servers: []xdsclient.ServerConfig{{\n        ServerIdentifier: clients.ServerIdentifier{ServerURI: \"trafficdirector.googleapis.com:443\"},\n    }},\n}\nclient, err := xdsclient.New(cfg)","handlingStrategy":"validation","validationCode":"func newXDSClientValidated(cfg xdsclient.Config) (*xdsclient.XDSClient, error) {\n    hasServers := len(cfg.Servers) > 0\n    hasAuthorities := false\n    for _, a := range cfg.Authorities {\n        if len(a.XDSServers) > 0 {\n            hasAuthorities = true\n            break\n        }\n    }\n    if !hasServers && !hasAuthorities {\n        return nil, errors.New(\"xdsclient.Config must specify at least one Server or an Authority with XDSServers\")\n    }\n    return xdsclient.New(cfg)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the bootstrap before constructing Config: require `xds_servers` or at least one authority.","Surface a clearer application-level error so users know which config file/section is wrong.","Add a startup self-test that fails fast if no servers are configured."],"tags":["grpc","xds","xdsclient","config-validation","bootstrap"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}