{"record":{"id":"52022667c743a7b0","repo":"grpc/grpc-go","slug":"grpctransport-extensions-is-not-set-in-serveriden","errorCode":null,"errorMessage":"grpctransport: Extensions is not set in ServerIdentifier","messagePattern":"grpctransport: Extensions is not set in ServerIdentifier","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/grpctransport/grpc_transport.go","lineNumber":94,"sourceCode":"// 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()\n\tdefer b.mu.Unlock()\n\n\tif cc, ok := b.connections[si]; ok {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/clients/grpctransport/grpc_transport.go#L76-L112","documentation":"Builder.Build requires that ServerIdentifier.Extensions is non-nil (grpc_transport.go:93-94), because the extension carries the ServerIdentifierExtension (including ConfigName) that selects which credentials configuration to use. A nil Extensions means there is no way to look up the transport config, so Build fails.","triggerScenarios":"Calling builder.Build(si) where si.Extensions was never set. The Builder is documented to require an Extension of type ServerIdentifierExtension.","commonSituations":"Constructing a ServerIdentifier programmatically and forgetting the Extensions field; migrating from an older API that did not require Extensions.","solutions":["Set si.Extensions = grpctransport.ServerIdentifierExtension{ConfigName: \"your-config\"} before calling Build.","Ensure the ConfigName used matches a key passed to NewBuilder.","Add a precondition assertion that Extensions is non-nil in calling code."],"exampleFix":"// before:\n//   si := clients.ServerIdentifier{ServerURI: \"dns:///xds:443\"}\n//   builder.Build(si) // Extensions nil\n// after:\n//   si := clients.ServerIdentifier{\n//     ServerURI:  \"dns:///xds:443\",\n//     Extensions: grpctransport.ServerIdentifierExtension{ConfigName: \"default\"},\n//   }","handlingStrategy":"validation","validationCode":"func validateServerIdentifier(si clients.ServerIdentifier) error {\n    if si.Extensions == nil {\n        return errors.New(\"ServerIdentifier.Extensions must be set\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set Extensions to a ServerIdentifierExtension when using grpctransport.","Use a constructor function for ServerIdentifiers used with this builder."],"tags":["xds","grpctransport","config","required-field","grpc"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}