grpc/grpc-go · error
grpctransport: failed to create connection to server %q: %v
Error message
grpctransport: failed to create connection to server %q: %v
What it means
After all validations pass, Build calls the gRPC new-client function (grpc.NewClient by default, or a custom GRPCNewClient) with the server URI and dial options including the credentials bundle and keepalive params (grpc_transport.go:135-137). If that call returns an error, it is wrapped with the server URI. This is a connection-creation failure, not a connection-establishment failure — grpc.NewClient is lazy, so most errors here come from invalid dial options or a custom client function.
Source
Thrown at internal/xds/clients/grpctransport/grpc_transport.go:137
return tr, nil
}
// Create a new gRPC client/channel for the server with the provided
// credentials, server URI, and a byte codec to send and receive messages.
// Also set a static keepalive configuration that is common across gRPC
// language implementations.
kpCfg := grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 5 * time.Minute,
Timeout: 20 * time.Second,
})
dopts := []grpc.DialOption{kpCfg, grpc.WithCredentialsBundle(config.Credentials), grpc.WithDefaultCallOptions(grpc.ForceCodec(&byteCodec{}))}
newClientFunc := grpc.NewClient
if config.GRPCNewClient != nil {
newClientFunc = config.GRPCNewClient
}
cc, err := newClientFunc(si.ServerURI, dopts...)
if err != nil {
return nil, fmt.Errorf("grpctransport: failed to create connection to server %q: %v", si.ServerURI, err)
}
tr := &grpcTransport{cc: cc}
// Register a cleanup function that decrements the refs to the gRPC
// transport each time Close() is called to close it and remove from
// transports and connections map if last reference is being released.
tr.cleanup = b.cleanupFunc(si, tr)
// Add the newly created connection to the maps to re-use the transport
// channel and track references.
b.connections[si] = cc
b.refs[si] = 1
if logger.V(2) {
logger.Infof("Created a new transport to the server for ServerIdentifier: %v", si)
}
return tr, nil
}
View on GitHub (pinned to 03255a9237)
Solutions
- Inspect the wrapped error (%v) — it distinguishes option errors from URI/resolver errors from custom-client errors.
- If using a custom GRPCNewClient, test it in isolation with the same target and options.
- Verify the ServerURI scheme (dns:///, xds:///, etc.) is supported and well-formed.
- Confirm the credentials bundle is compatible with the transport; remove conflicting DialOptions.
- For transient network issues inside a custom client, consider retrying Build after a backoff.
Example fix
// before:
// builder with a custom GRPCNewClient that dials eagerly and fails
// after:
// test the custom client separately:
// cc, err := myClientFunc("dns:///xds:443", dopts...)
// if err != nil { log.Printf("dial option error: %v", err) }
// // or simplify by using the default grpc.NewClient (GRPCNewClient = nil) Defensive patterns
Strategy: try-catch
Validate before calling
// If using a custom GRPCNewClient, sanity-check the target first.
func validateTarget(uri string) error {
if uri == "" { return errors.New("empty target") }
// ensure the scheme is recognized by the gRPC resolver registry
return nil
} Try / catch
tr, err := builder.Build(si)
if err != nil {
if strings.Contains(err.Error(), "failed to create connection") {
// inspect wrapped cause; retry transient failures after backoff
return fmt.Errorf("transport build failed for %q: %w", si.ServerURI, err)
}
return err
} Prevention
- Test custom GRPCNewClient implementations in isolation before wiring them into Config.
- Verify the ServerURI scheme is supported by the resolver registry.
- Inspect the wrapped error to separate option errors from network errors before retrying.
When it happens
Trigger: grpc.NewClient (or a custom GRPCNewClient) returns a non-nil error — typically because a DialOption is invalid (e.g. conflicting credentials), the target URI is malformed in a way the resolver rejects immediately, or a custom new-client function has its own precondition that failed.
Common situations: The credentials bundle is incompatible with the target scheme; a custom GRPCNewClient performs eager validation or dialing and the server is unreachable; the ServerURI uses a scheme/resolver that errors at construction; environment (proxy) settings interfere with name resolution at client creation.
Related errors
- grpctransport: ServerURI is not set in ServerIdentifier
- grpctransport: Extensions is not set in ServerIdentifier
- grpctransport: Extensions field is %T, but must be %T in Ser
- grpctransport: unknown config name %q specified in ServerIde
- grpctransport: config %q has nil credentials bundle
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/cf9a6a3e3a196e69.
Report an issue: GitHub.