{"record":{"id":"bbcf7179fe45c777","repo":"grpc/grpc-go","slug":"unsupported-mode-v","errorCode":null,"errorMessage":"unsupported mode: %v","messagePattern":"unsupported mode: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/google/google.go","lineNumber":146,"sourceCode":"\n// NewWithMode should make a copy of Bundle, and switch mode. Modifying the\n// existing Bundle may cause races.\nfunc (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {\n\tnewCreds := &creds{\n\t\topts: c.opts,\n\t\tmode: mode,\n\t}\n\n\t// Create transport credentials.\n\tswitch mode {\n\tcase internal.CredsBundleModeFallback:\n\t\tnewCreds.transportCreds = newClusterTransportCreds(newTLS(), newALTS())\n\tcase internal.CredsBundleModeBackendFromBalancer, internal.CredsBundleModeBalancer:\n\t\t// Only the clients can use google default credentials, so we only need\n\t\t// to create new ALTS client creds here.\n\t\tnewCreds.transportCreds = newALTS()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported mode: %v\", mode)\n\t}\n\n\tif mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {\n\t\tnewCreds.perRPCCreds = newCreds.opts.PerRPCCreds\n\t}\n\n\treturn newCreds, nil\n}\n\n// dualPerRPCCreds implements credentials.PerRPCCredentials by embedding the\n// fallback PerRPCCredentials and the ALTS one. It pickes one of them based on\n// the channel type.\ntype dualPerRPCCreds struct {\n\tperRPCCreds     credentials.PerRPCCredentials\n\taltsPerRPCCreds credentials.PerRPCCredentials\n}\n\nfunc (d *dualPerRPCCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/google/google.go#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbundle, err := creds.NewWithMode(\"mtls\") // not supported\n\n// after\nbundle, err := creds.NewWithMode(internal.CredsBundleModeFallback)","handlingStrategy":"validation","validationCode":"// Allow-list modes before calling NewWithMode.\nfunc validBundleMode(m string) bool {\n    switch m {\n    case internal.CredsBundleModeFallback,\n        internal.CredsBundleModeBackendFromBalancer,\n        internal.CredsBundleModeBalancer:\n        return true\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":"b, err := c.NewWithMode(mode)\nif err != nil && strings.Contains(err.Error(), \"unsupported mode\") {\n    return nil, fmt.Errorf(\"invalid credential bundle mode %q: %w\", mode, err)\n}","preventionTips":["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."],"tags":["grpc","credentials","configuration","validation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}