vitessio/vitess · error
no dialer registered for VTGate protocol %s
Error message
no dialer registered for VTGate protocol %s
What it means
vtgateconn.DialProtocol looks up a client dialer in a registry keyed by protocol name (e.g. 'grpc'). If no dialer has been registered for the given protocol string, dialing cannot proceed and this error is returned. It is a pure client-side configuration/naming error.
Source
Thrown at go/vt/vtgate/vtgateconn/vtgateconn.go:270
// DeregisterDialer removes the named DialerFunc from the registered list of
// dialers. If the named DialerFunc does not exist, it is a noop.
//
// This is useful to avoid unbounded memory use if many different dialer
// implementations are used throughout the lifetime of a program.
func DeregisterDialer(name string) {
dialersM.Lock()
defer dialersM.Unlock()
delete(dialers, name)
}
// DialProtocol dials a specific protocol, and returns the *VTGateConn
func DialProtocol(ctx context.Context, protocol string, address string) (*VTGateConn, error) {
dialersM.Lock()
dialer, ok := dialers[protocol]
dialersM.Unlock()
if !ok {
return nil, fmt.Errorf("no dialer registered for VTGate protocol %s", protocol)
}
impl, err := dialer(ctx, address)
if err != nil {
return nil, err
}
return &VTGateConn{
impl: impl,
}, nil
}
// Dial dials using the command-line specified protocol, and returns
// the *VTGateConn.
func Dial(ctx context.Context, address string) (*VTGateConn, error) {
return DialProtocol(ctx, vtgateProtocol, address)
}
// DialCustom creates a new VTGateConn with the given DialerFunc.
func DialCustom(ctx context.Context, dialer DialerFunc, address string) (*VTGateConn, error) {View on GitHub (pinned to 01a25a7d17)
Solutions
- Use the exact registered protocol name, typically "grpc": vtgateconn.DialProtocol(ctx, "grpc", address)
- Verify your binary imports the dialer package (e.g. _ "vitess.io/vitess/go/vt/vtgate/grpcvtgateconn") so its init registers the dialer
- Print registered keys or check code: dialers map keys in vtgateconn
- If using a smart client (DialVTGate / go/vt/discovery), confirm the vtgate address scheme matches a supported protocol
Example fix
// before conn, err := vtgateconn.DialProtocol(ctx, "grpcs", "localhost:15991") // after import _ "vitess.io/vitess/go/vt/vtgate/grpcvtgateconn" conn, err := vtgateconn.DialProtocol(ctx, "grpc", "localhost:15991")
Defensive patterns
Strategy: validation
Validate before calling
// Go: verify the grpc dialer is registered before dialing
import _ "vitess.io/vitess/go/vt/vtgate/grpcvtgateconn"
func protocolSupported(p string) bool {
return p == "grpc" // dialers registry keys; check vtgateconn source for others
} Try / catch
conn, err := vtgateconn.DialProtocol(ctx, "grpc", addr)
if err != nil {
if strings.Contains(err.Error(), "no dialer registered") {
return nil, fmt.Errorf("protocol %q unavailable: ensure grpcvtgateconn is imported", addr)
}
return nil, err
} Prevention
- Always use the literal protocol name "grpc" unless you registered a custom dialer
- Blank-import the dialer package (grpcvtgateconn) in any binary that dials vtgate
- Centralize dialing in one helper so the protocol string appears once
- Write a smoke test that dials vtgate at startup to fail fast on registry issues
When it happens
Trigger: Calling vtgateconn.DialProtocol(ctx, protocol, address) with a protocol string that was never registered via RegisterDialer, e.g. typo 'grpcs', or a build/tag that excludes the grpc dialer registration.
Common situations: Typos in the protocol part of a vtgate address ('grpc' vs 'grpc+' prefix confusion), using a custom binary that does not import the grpc dialer package, or tests/tools built without the expected dialer registration.
Related errors
- unknown mysqlctl client protocol: %v
- unknown vtctl client protocol: %v
- unknown vtctld client protocol: %s
- --buffer-window must be >= 1s (specified value: %v)
- --buffer-window must be <= --buffer-max-failover-duration: %
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/54daa7354af8cd69.
Report an issue: GitHub.