grpc/grpc-go · error
grpc: credentials.Bundle must return non-nil transport crede
Error message
grpc: credentials.Bundle must return non-nil transport credentials
What it means
errNoTransportCredsInBundle (clientconn.go:94-96) is returned by validateTransportCredentials (clientconn.go:487-489) when a CredsBundle is configured but its TransportCredentials() method returns nil. A bundle MUST supply non-nil transport credentials to be usable.
Source
Thrown at clientconn.go:96
// invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default
// service config.
invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid"
// PickFirstBalancerName is the name of the pick_first balancer.
PickFirstBalancerName = pickfirst.Name
)
// The following errors are returned from Dial and DialContext
var (
// errNoTransportSecurity indicates that there is no transport security
// being set for ClientConn. Users should either set one or explicitly
// call WithInsecure DialOption to disable security.
errNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithTransportCredentials(insecure.NewCredentials()) explicitly or set credentials)")
// errTransportCredsAndBundle indicates that creds bundle is used together
// with other individual Transport Credentials.
errTransportCredsAndBundle = errors.New("grpc: credentials.Bundle may not be used with individual TransportCredentials")
// errNoTransportCredsInBundle indicated that the configured creds bundle
// returned a transport credentials which was nil.
errNoTransportCredsInBundle = errors.New("grpc: credentials.Bundle must return non-nil transport credentials")
// errTransportCredentialsMissing indicates that users want to transmit
// security information (e.g., OAuth2 token) which requires secure
// connection on an insecure connection.
errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)")
)
var (
disconnectionsMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{
Name: "grpc.subchannel.disconnections",
Description: "EXPERIMENTAL. Number of times the selected subchannel becomes disconnected.",
Unit: "{disconnection}",
Labels: []string{"grpc.target"},
OptionalLabels: []string{"grpc.lb.backend_service", "grpc.lb.locality", "grpc.disconnect_error"},
Default: false,
})
connectionAttemptsSucceededMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{
Name: "grpc.subchannel.connection_attempts_succeeded",
Description: "EXPERIMENTAL. Number of successful connection attempts.",View on GitHub (pinned to 03255a9237)
Solutions
- Fix the bundle implementation so TransportCredentials() returns a valid TransportCredentials (e.g. credentials.NewTLS(tlsConf) or insecure.NewCredentials()).
- If you only need per-RPC creds, use WithPerRPCCredentials(...) plus an explicit WithTransportCredentials(...) instead of a bundle.
- Add a unit test asserting bundle.TransportCredentials() != nil before passing it to NewClient.
- If using a Google-provided bundle, ensure it is the right constructor (e.g. oauth bundle variants) for your transport.
Example fix
// before — custom bundle with nil transport creds
type myBundle struct{}
func (b *myBundle) TransportCredentials() credentials.TransportCredentials { return nil }
cc, _ := grpc.NewClient(target, grpc.WithCredentialsBundle(&myBundle{}))
// err: grpc: credentials.Bundle must return non-nil transport credentials
// after — return real transport creds
func (b *myBundle) TransportCredentials() credentials.TransportCredentials {
return credentials.NewTLS(b.tlsConf)
} Defensive patterns
Strategy: type-guard
Validate before calling
// Validate a bundle before handing it to NewClient
func requireBundleTransport(b credentials.Bundle) error {
if b == nil || b.TransportCredentials() == nil {
return errors.New("bundle must provide non-nil transport credentials")
}
return nil
} Type guard
func hasTransportCreds(b credentials.Bundle) bool {
return b != nil && b.TransportCredentials() != nil
} Try / catch
cc, err := grpc.NewClient(target, grpc.WithCredentialsBundle(b))
if err != nil && strings.Contains(err.Error(), "Bundle must return non-nil") {
// fix the bundle impl or switch to WithTransportCredentials
} Prevention
- Unit-test custom bundles: assert TransportCredentials() != nil.
- Prefer WithPerRPCCredentials + WithTransportCredentials when a bundle is overkill.
- Pin bundle constructor to a known-good implementation.
When it happens
Trigger: A custom credentials.Bundle implementation returns nil from TransportCredentials(), or a malformed/partial bundle is passed via WithCredentialsBundle. The check at clientconn.go:487 catches it at construction time.
Common situations: Hand-written or third-party CredsBundle that only implements PerRPCCredentials but leaves TransportCredentials() returning nil; using a bundle type that was only meant for a specific environment; refactor that dropped the TLS branch.
Related errors
- grpc: no transport security set (use grpc.WithTransportCrede
- grpc: credentials.Bundle may not be used with individual Tra
- grpc: the credentials require transport level security (use
- AuthInfo is nil
- ALTS: untrusted platform. ALTS is only supported on GCP
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/d2936028ec240f83.
Report an issue: GitHub.