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

  1. Only pass the documented constants: CredsBundleModeFallback, CredsBundleModeBackendFromBalancer, CredsBundleModeBalancer.
  2. If surfacing mode from config, validate against an allow-list before calling NewWithMode.
  3. 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

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


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/bbcf7179fe45c777. Report an issue: GitHub.