grpc/grpc-go · error
missing fallback credentials
Error message
missing fallback credentials
What it means
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.
Source
Thrown at credentials/xds/xds.go:50
xdsinternal "google.golang.org/grpc/internal/credentials/xds"
"google.golang.org/grpc/internal/grpcsync"
)
// ClientOptions contains parameters to configure a new client-side xDS
// credentials implementation.
type ClientOptions struct {
// FallbackCreds specifies the fallback credentials to be used when either
// the `xds` scheme is not used in the user's dial target or when the
// management server does not return any security configuration. Attempts to
// create client credentials without fallback credentials will fail.
FallbackCreds credentials.TransportCredentials
}
// NewClientCredentials returns a new client-side transport credentials
// implementation which uses xDS APIs to fetch its security configuration.
func NewClientCredentials(opts ClientOptions) (credentials.TransportCredentials, error) {
if opts.FallbackCreds == nil {
return nil, errors.New("missing fallback credentials")
}
return &credsImpl{
isClient: true,
fallback: opts.FallbackCreds,
}, nil
}
// ServerOptions contains parameters to configure a new server-side xDS
// credentials implementation.
type ServerOptions struct {
// FallbackCreds specifies the fallback credentials to be used when the
// management server does not return any security configuration. Attempts to
// create server credentials without fallback credentials will fail.
FallbackCreds credentials.TransportCredentials
}
// NewServerCredentials returns a new server-side transport credentials
// implementation which uses xDS APIs to fetch its security configuration.View on GitHub (pinned to 03255a9237)
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).
Example fix
// before
c, _ := xds.NewClientCredentials(xds.ClientOptions{}) // err: missing fallback credentials
// after
c, err := xds.NewClientCredentials(xds.ClientOptions{
FallbackCreds: insecure.NewCredentials(),
}) Defensive patterns
Strategy: validation
Validate before calling
if opts.FallbackCreds == nil {
return errors.New("xds client credentials require FallbackCreds (e.g. insecure.NewCredentials())")
}
c, err := xds.NewClientCredentials(opts) Try / catch
c, err := xds.NewClientCredentials(opts)
if err != nil { log.Fatalf("xds client creds: %v", err) } Prevention
- Always pair xDS client creds with an explicit fallback.
- Decide fallback semantics (insecure vs TLS) intentionally and document it.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- empty token_exchange_service_uri in options
- required field SubjectTokenPath is not specified
- required field SubjectTokenType is not specified
- ClientHandshake() is not supported for server credentials
- ServerHandshake is not supported for client credentials
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/b1b92814a30a803a.
Report an issue: GitHub.