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

  1. Pass a non-nil fallback credentials, most commonly insecure.NewCredentials() or credentials.NewTLS(&tls.Config{}).
  2. Always check the error returned by NewClientCredentials.
  3. 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

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


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