grpc/grpc-go · error
unsupported mode: %v
Error message
unsupported mode: %v
What it means
creds.NewWithMode returns this for any mode string outside the three recognized constants (google.go:138-147): internal.CredsBundleModeFallback, CredsBundleModeBackendFromBalancer, CredsBundleModeBalancer. NewWithMode is part of the credentials.Bundle interface and is normally only called by gRPC internals; a custom mode indicates misuse.
Source
Thrown at credentials/google/google.go:146
// NewWithMode should make a copy of Bundle, and switch mode. Modifying the
// existing Bundle may cause races.
func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {
newCreds := &creds{
opts: c.opts,
mode: mode,
}
// Create transport credentials.
switch mode {
case internal.CredsBundleModeFallback:
newCreds.transportCreds = newClusterTransportCreds(newTLS(), newALTS())
case internal.CredsBundleModeBackendFromBalancer, internal.CredsBundleModeBalancer:
// Only the clients can use google default credentials, so we only need
// to create new ALTS client creds here.
newCreds.transportCreds = newALTS()
default:
return nil, fmt.Errorf("unsupported mode: %v", mode)
}
if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {
newCreds.perRPCCreds = newCreds.opts.PerRPCCreds
}
return newCreds, nil
}
// dualPerRPCCreds implements credentials.PerRPCCredentials by embedding the
// fallback PerRPCCredentials and the ALTS one. It pickes one of them based on
// the channel type.
type dualPerRPCCreds struct {
perRPCCreds credentials.PerRPCCredentials
altsPerRPCCreds credentials.PerRPCCredentials
}
func (d *dualPerRPCCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {View on GitHub (pinned to 03255a9237)
Solutions
- Only pass the documented constants: CredsBundleModeFallback, CredsBundleModeBackendFromBalancer, CredsBundleModeBalancer.
- If surfacing mode from config, validate against an allow-list before calling NewWithMode.
- Upgrade grpc-go if a newer internal mode is required by your transport stack.
Example fix
// before
bundle, err := creds.NewWithMode("mtls") // not supported
// after
bundle, err := creds.NewWithMode(internal.CredsBundleModeFallback) Defensive patterns
Strategy: validation
Validate before calling
// Allow-list modes before calling NewWithMode.
func validBundleMode(m string) bool {
switch m {
case internal.CredsBundleModeFallback,
internal.CredsBundleModeBackendFromBalancer,
internal.CredsBundleModeBalancer:
return true
}
return false
} Try / catch
b, err := c.NewWithMode(mode)
if err != nil && strings.Contains(err.Error(), "unsupported mode") {
return nil, fmt.Errorf("invalid credential bundle mode %q: %w", mode, err)
} Prevention
- Only pass the documented internal.CredsBundleMode* constants.
- Validate user/config-supplied mode strings against an allow-list.
- Avoid calling NewWithMode directly from application code; let gRPC internals drive it.
When it happens
Trigger: Calling NewWithMode with an arbitrary string, or a caller reading a mode from config/env without validating against the known set. The switch in google.go:138 has no default-accept branch.
Common situations: Custom code that iterates over user-supplied mode names, a gRPC internal version that introduced a new mode not yet handled by this google bundle build, or a typo in the mode constant reference.
Related errors
- credentials: ctx cannot be nil
- credentials: audience cannot be empty
- token file %q: %v: %w
- no expiration claims
- requires SecurityLevel %v; connection has %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/bbcf7179fe45c777.
Report an issue: GitHub.