{"record":{"id":"6c6e7f8b4f06704e","repo":"vitessio/vitess","slug":"unknown-vtctl-client-protocol-v","errorCode":null,"errorMessage":"unknown vtctl client protocol: %v","messagePattern":"unknown vtctl client protocol: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/vtctlclient/interface.go","lineNumber":78,"sourceCode":"// Factory functions are registered by client implementations\ntype Factory func(ctx context.Context, addr string) (VtctlClient, error)\n\nvar factories = make(map[string]Factory)\n\n// RegisterFactory allows a client implementation to register itself.\nfunc RegisterFactory(name string, factory Factory) {\n\tif _, ok := factories[name]; ok {\n\t\tlog.Error(fmt.Sprintf(\"RegisterFactory: %s already exists\", name))\n\t\tos.Exit(1)\n\t}\n\tfactories[name] = factory\n}\n\n// New allows a user of the client library to get its implementation.\nfunc New(ctx context.Context, addr string) (VtctlClient, error) {\n\tfactory, ok := factories[vtctlClientProtocol]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unknown vtctl client protocol: %v\", vtctlClientProtocol)\n\t}\n\treturn factory(ctx, addr)\n}\n","sourceCodeStart":60,"sourceCodeEnd":82,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/vtctlclient/interface.go#L60-L82","documentation":"The legacy vtctl client library resolves its implementation through a factory registry keyed by the vtctlClientProtocol package variable. When New() looks up the protocol and finds no registered factory, it refuses to build a client with this error. It means the binary was linked without any client implementation registered for the configured protocol.","triggerScenarios":"Calling vtctlclient.New(ctx, addr) (directly or via RunCommandAndWait) when vtctlClientProtocol is set to a value for which no factory was registered via the RegisterXxxClient init hooks (e.g. gRPC client package not imported/linked).","commonSituations":"Building a custom vtctl binary that forgot to import the grpc vtctlclient implementation; running 'go run' on a subset of packages; flag misconfiguration setting an unsupported protocol value.","solutions":["Blank-import the gRPC client implementation so its init registers the factory: _ \"vitess.io/vitess/go/vt/vtctl/vtctlclient/grpcvtctlclient\"","Check the vtctl_client_protocol flag value matches a registered protocol (e.g. grpc)","Build the standard vtctlclient/vtctl binaries instead of a trimmed custom binary","Verify with go build that the binary includes the implementation package"],"exampleFix":"// before\nimport \"vitess.io/vitess/go/vt/vtctl/vtctlclient\"\n// after\nimport (\n  _ \"vitess.io/vitess/go/vt/vtctl/vtctlclient/grpcvtctlclient\"\n  \"vitess.io/vitess/go/vt/vtctl/vtctlclient\"\n)","handlingStrategy":"validation","validationCode":"// before dialing, ensure the grpc implementation is linked\nimport _ \"vitess.io/vitess/go/vt/vtctl/vtctlclient/grpcvtctlclient\"","typeGuard":"func clientFactoryRegistered(protocol string) bool {\n  return protocol == \"grpc\" // only registered protocol in stock builds\n}","tryCatchPattern":"client, err := vtctlclient.New(ctx, addr)\nif err != nil {\n  if strings.Contains(err.Error(), \"unknown vtctl client protocol\") {\n    return fmt.Errorf(\"client not linked for protocol; import grpcvtctlclient: %w\", err)\n  }\n  return err\n}","preventionTips":["Always blank-import grpcvtctlclient in binaries using vtctlclient","Pin the -vtctl_client_protocol flag to a known value in scripts","Smoke-test custom builds with a trivial vtctl command before deploying"],"tags":["go","vtctl","client","configuration","factory"],"backgroundTag":"unknown-protocol","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}