{"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/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/grpctransport/grpc_transport.go#L88-L124","documentation":"Returned when the Config referenced by ConfigName exists but its Credentials field is nil (grpc_transport.go:106). The Builder needs a non-nil credentials.Bundle to construct DialOptions, so a registered-but-empty config is rejected before dialing.","triggerScenarios":"grpctransport.NewBuilder is called with a map entry like \"mtls\": {Credentials: nil}. Build resolves the config successfully then fails the nil check.","commonSituations":"Config was registered as a placeholder; tlscreds.NewBundle failed earlier and the caller stored a nil bundle instead of propagating the error; the credentials field was omitted in a struct literal.","solutions":["Ensure tlscreds.NewBundle (or equivalent) succeeds before registering the Config.","Propagate bundle-construction errors at bootstrap time rather than storing nil.","Add a startup assertion that every Config in the map has non-nil Credentials."],"exampleFix":"// before\nb, _, err := tlscreds.NewBundle(cfg)\n// err ignored, b may be nil\nbuilder := grpctransport.NewBuilder(map[string]Config{\"mtls\": {Credentials: nil}})\n\n// after\nb, closeFn, err := tlscreds.NewBundle(cfg)\nif err != nil { return err }\nbuilder := grpctransport.NewBuilder(map[string]Config{\"mtls\": {Credentials: b}})","handlingStrategy":"validation","validationCode":"for name, cfg := range configs {\n    if cfg.Credentials == nil {\n        return fmt.Errorf(\"config %q has nil credentials\", name)\n    }\n}\nbuilder := grpctransport.NewBuilder(configs)","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"nil credentials bundle\") {\n    // build the bundle first, propagate any error, then register\n}","preventionTips":["Always propagate errors from tlscreds.NewBundle; never store a nil bundle.","Add a startup assertion that every Config has non-nil Credentials.","Initialize bundles in a single function and fail fast on error."],"tags":["grpctransport","xds","credentials","configuration"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}