{"record":{"id":"34249a342e6a46fc","repo":"grpc/grpc-go","slug":"grpctransport-serveruri-is-not-set-in-serverident","errorCode":null,"errorMessage":"grpctransport: ServerURI is not set in ServerIdentifier","messagePattern":"grpctransport: ServerURI is not set in ServerIdentifier","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/grpctransport/grpc_transport.go","lineNumber":91,"sourceCode":"}\n\n// NewBuilder provides a builder for creating gRPC-based Transports using\n// the credentials from provided map of credentials names to\n// credentials.Bundle.\nfunc NewBuilder(configs map[string]Config) *Builder {\n\treturn &Builder{\n\t\tconfigs:     configs,\n\t\tconnections: make(map[clients.ServerIdentifier]*grpc.ClientConn),\n\t\trefs:        make(map[clients.ServerIdentifier]int),\n\t}\n}\n\n// Build returns a gRPC-based clients.Transport.\n//\n// The Extension field of the ServerIdentifier must be a ServerIdentifierExtension.\nfunc (b *Builder) Build(si clients.ServerIdentifier) (clients.Transport, error) {\n\tif si.ServerURI == \"\" {\n\t\treturn nil, fmt.Errorf(\"grpctransport: ServerURI is not set in ServerIdentifier\")\n\t}\n\tif si.Extensions == nil {\n\t\treturn nil, fmt.Errorf(\"grpctransport: Extensions is not set in ServerIdentifier\")\n\t}\n\tsce, ok := si.Extensions.(ServerIdentifierExtension)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"grpctransport: Extensions field is %T, but must be %T in ServerIdentifier\", si.Extensions, ServerIdentifierExtension{})\n\t}\n\n\tconfig, ok := b.configs[sce.ConfigName]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"grpctransport: unknown config name %q specified in ServerIdentifierExtension\", sce.ConfigName)\n\t}\n\tif config.Credentials == nil {\n\t\treturn nil, fmt.Errorf(\"grpctransport: config %q has nil credentials bundle\", sce.ConfigName)\n\t}\n\n\tb.mu.Lock()","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/grpctransport/grpc_transport.go#L73-L109","documentation":"Returned by (*Builder).Build when clients.ServerIdentifier.ServerURI is the empty string (grpc_transport.go:91). Build requires a non-empty target URI because it is passed directly to grpc.NewClient; an empty URI is treated as a configuration error rather than a dial error.","triggerScenarios":"Calling builder.Build(si) where si.ServerURI == \"\". Common when the ServerIdentifier is constructed from a bootstrap xds_server entry whose server_uri field is missing.","commonSituations":"Bootstrap configuration JSON is missing the \"server_uri\" field on an xds_server; a templated config left the URI blank; the LRS server config reuses an xDS server entry without copying the URI; programmatic bootstrap assembly bug.","solutions":["Inspect the bootstrap configuration and ensure every xds_server / lrs_server has a non-empty server_uri.","If building ServerIdentifier in code, validate ServerURI before calling Build.","Log the offending ServerIdentifier at the call site to pinpoint which entry is empty."],"exampleFix":"// before\nsi := clients.ServerIdentifier{} // ServerURI empty\ntr, err := builder.Build(si)\n\n// after\nif si.ServerURI == \"\" {\n    return fmt.Errorf(\"server URI required for %v\", si)\n}\ntr, err := builder.Build(si)","handlingStrategy":"validation","validationCode":"func validServerIdentifier(si clients.ServerIdentifier) error {\n    if si.ServerURI == \"\" {\n        return errors.New(\"ServerURI must be set\")\n    }\n    return nil\n}\n// call before builder.Build(si)","typeGuard":null,"tryCatchPattern":"tr, err := builder.Build(si)\nif err != nil && strings.Contains(err.Error(), \"ServerURI is not set\") {\n    // bootstrap is missing server_uri; fail fast with context\n}","preventionTips":["Validate bootstrap JSON with a schema check that requires server_uri on every xds_server.","Build ServerIdentifier in one helper and unit-test it.","Log the ServerIdentifier at debug level before Build to catch empty fields."],"tags":["grpctransport","xds","configuration","bootstrap","validation"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}