{"record":{"id":"8fe0af01e084637d","repo":"grpc/grpc-go","slug":"grpctransport-config-q-has-nil-credentials-bundl","errorCode":null,"errorMessage":"grpctransport: config %q has nil credentials bundle","messagePattern":"grpctransport: config %q has nil credentials bundle","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/grpctransport/grpc_transport.go","lineNumber":106,"sourceCode":"// 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 {\n\t\tif logger.V(2) {\n\t\t\tlogger.Infof(\"Reusing existing connection to the server for ServerIdentifier: %v\", si)\n\t\t}\n\t\tb.refs[si]++\n\t\ttr := &grpcTransport{cc: cc}\n\t\ttr.cleanup = b.cleanupFunc(si, tr)\n\t\treturn tr, nil\n\t}\n\n\t// Create a new gRPC client/channel for the server with the provided\n\t// credentials, server URI, and a byte codec to send and receive messages.\n\t// Also set a static keepalive configuration that is common across gRPC","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/clients/grpctransport/grpc_transport.go#L88-L124","documentation":"The Config selected by ConfigName must have a non-nil Credentials bundle (grpc_transport.go:105-106) because the gRPC dial options include grpc.WithCredentialsBundle(config.Credentials). A nil bundle would produce a broken channel, so Build rejects it upfront. The offending config name is reported.","triggerScenarios":"A Config entry was added to the NewBuilder map with Config.Credentials left nil. This can happen when the config was partially initialized or a credentials bundle failed to build but the empty Config was still registered.","commonSituations":"The credentials.Bundle was supposed to be created from tlscreds.NewBundle or similar but the call was omitted or its error ignored; a config was templated in without the credentials step.","solutions":["Set Config.Credentials to a valid credentials.Bundle (e.g. from tlscreds.NewBundle or credentials.NewTLS) before adding it to the map.","If credential creation can fail, handle the error and skip registering that Config rather than registering one with nil Credentials.","Add a precondition loop after building the configs map to assert none have nil Credentials."],"exampleFix":"// before:\n//   builder := grpctransport.NewBuilder(map[string]Config{\n//     \"default\": { Credentials: nil },\n//   })\n// after:\n//   bdl, closeFn, err := tlscreds.NewBundle(cfg)\n//   if err != nil { return err }\n//   builder := grpctransport.NewBuilder(map[string]Config{\n//     \"default\": { Credentials: bdl },\n//   })","handlingStrategy":"validation","validationCode":"func validateConfigs(configs map[string]grpctransport.Config) error {\n    for name, cfg := range configs {\n        if cfg.Credentials == nil {\n            return fmt.Errorf(\"config %q has nil Credentials\", name)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always populate Config.Credentials when building the configs map.","Do not register a Config whose credential creation failed; skip or fail instead."],"tags":["xds","grpctransport","credentials","config","grpc"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}