{"record":{"id":"b1b92814a30a803a","repo":"grpc/grpc-go","slug":"missing-fallback-credentials","errorCode":null,"errorMessage":"missing fallback credentials","messagePattern":"missing fallback credentials","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/xds/xds.go","lineNumber":50,"sourceCode":"\txdsinternal \"google.golang.org/grpc/internal/credentials/xds\"\n\t\"google.golang.org/grpc/internal/grpcsync\"\n)\n\n// ClientOptions contains parameters to configure a new client-side xDS\n// credentials implementation.\ntype ClientOptions struct {\n\t// FallbackCreds specifies the fallback credentials to be used when either\n\t// the `xds` scheme is not used in the user's dial target or when the\n\t// management server does not return any security configuration. Attempts to\n\t// create client credentials without fallback credentials will fail.\n\tFallbackCreds credentials.TransportCredentials\n}\n\n// NewClientCredentials returns a new client-side transport credentials\n// implementation which uses xDS APIs to fetch its security configuration.\nfunc NewClientCredentials(opts ClientOptions) (credentials.TransportCredentials, error) {\n\tif opts.FallbackCreds == nil {\n\t\treturn nil, errors.New(\"missing fallback credentials\")\n\t}\n\treturn &credsImpl{\n\t\tisClient: true,\n\t\tfallback: opts.FallbackCreds,\n\t}, nil\n}\n\n// ServerOptions contains parameters to configure a new server-side xDS\n// credentials implementation.\ntype ServerOptions struct {\n\t// FallbackCreds specifies the fallback credentials to be used when the\n\t// management server does not return any security configuration. Attempts to\n\t// create server credentials without fallback credentials will fail.\n\tFallbackCreds credentials.TransportCredentials\n}\n\n// NewServerCredentials returns a new server-side transport credentials\n// implementation which uses xDS APIs to fetch its security configuration.","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/xds/xds.go#L32-L68","documentation":"Returned by NewClientCredentials (credentials/xds/xds.go:50) when opts.FallbackCreds is nil. xDS client credentials need a fallback TransportCredentials to use when the dial target does not use the xds:// scheme or the management server returns no security config (see ClientHandshake at xds.go:113-115, 123-125). The constructor hard-requires it.","triggerScenarios":"Calling xds.NewClientCredentials(ClientOptions{}) or NewClientCredentials(ClientOptions{FallbackCreds: nil}). It fails synchronously at construction; using the nil return value later causes a nil-pointer panic.","commonSituations":"Assuming insecure or system-default fallback is implied (it is not); migrating from grpc.WithTransportCredentials(insecure) to xDS creds and forgetting to pass the fallback; docs example that omitted the field.","solutions":["Pass a non-nil fallback credentials, most commonly insecure.NewCredentials() or credentials.NewTLS(&tls.Config{}).","Always check the error returned by NewClientCredentials.","Decide intentionally what fallback means for your app (plaintext-insecure vs. an alternative TLS config)."],"exampleFix":"// before\nc, _ := xds.NewClientCredentials(xds.ClientOptions{}) // err: missing fallback credentials\n\n// after\nc, err := xds.NewClientCredentials(xds.ClientOptions{\n    FallbackCreds: insecure.NewCredentials(),\n})","handlingStrategy":"validation","validationCode":"if opts.FallbackCreds == nil {\n    return errors.New(\"xds client credentials require FallbackCreds (e.g. insecure.NewCredentials())\")\n}\nc, err := xds.NewClientCredentials(opts)","typeGuard":null,"tryCatchPattern":"c, err := xds.NewClientCredentials(opts)\nif err != nil { log.Fatalf(\"xds client creds: %v\", err) }","preventionTips":["Always pair xDS client creds with an explicit fallback.","Decide fallback semantics (insecure vs TLS) intentionally and document it."],"tags":["go","grpc","security","xds","credentials","config-validation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}