{"record":{"id":"3eb3984cfcd6398a","repo":"vitessio/vitess","slug":"unknown-vtctld-client-protocol-s","errorCode":null,"errorMessage":"unknown vtctld client protocol: %s","messagePattern":"unknown vtctld client protocol: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/vtctldclient/client.go","lineNumber":63,"sourceCode":"\tif _, ok := registry[name]; ok {\n\t\tlog.Fatalf(\"Register: %s already registered\", name)\n\t}\n\n\tregistry[name] = factory\n}\n\n// New returns a VtctldClient for the given protocol, connected to a\n// VtctldServer on the given addr. This function returns an error if no client\n// factory was registered for the given protocol.\n//\n// This is a departure from vtctlclient's New, which relies on a flag in the\n// global namespace to determine the protocol to use. Instead, we require\n// users to specify their own flag in their own (hopefully not global) namespace\n// to determine the protocol to pass into here.\nfunc New(ctx context.Context, protocol string, addr string) (VtctldClient, error) {\n\tfactory, ok := registry[protocol]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unknown vtctld client protocol: %s\", protocol)\n\t}\n\n\treturn factory(ctx, addr)\n}\n","sourceCodeStart":45,"sourceCodeEnd":68,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/vtctldclient/client.go#L45-L68","documentation":"The vtctldclient package creates clients through a registry keyed by an explicit protocol string; New() returns this error when the passed protocol has no registered factory. Unlike the legacy client, the protocol is a parameter chosen by the caller (usually a flag in the consuming binary). It is a configuration/linkage error, not a network error.","triggerScenarios":"Calling vtctldclient.New(ctx, protocol, addr) where protocol is not a key in registry — e.g. passing \"grpc\" without importing the grpc client package so its init never registers, or a typo like \"gprc\".","commonSituations":"Flag default not set or misspelled in a tool embedding vtctldclient; trimmed custom binary missing the grpcvtctldclient import; switching protocol names across Vitess versions.","solutions":["Blank-import the implementation: _ \"vitess.io/vitess/go/vt/vtctl/vtctldclient/grpcvtctldclient\"","Correct the protocol flag value (typically \"grpc\") passed to vtctldclient.New","Check for typos and case sensitivity in the protocol string","Regenerate/rebuild any vtctldclient codegen'd client so the registry initialization is present"],"exampleFix":"// before\nclient, err := vtctldclient.New(ctx, \"gprc\", addr)\n// after\nimport _ \"vitess.io/vitess/go/vt/vtctl/vtctldclient/grpcvtctldclient\"\nclient, err := vtctldclient.New(ctx, \"grpc\", addr)","handlingStrategy":"validation","validationCode":"import _ \"vitess.io/vitess/go/vt/vtctl/vtctldclient/grpcvtctldclient\"\nif protocol != \"grpc\" {\n  return fmt.Errorf(\"unsupported protocol %q\", protocol)\n}","typeGuard":"func validVtctldProtocol(p string) bool { return p == \"grpc\" }","tryCatchPattern":"client, err := vtctldclient.New(ctx, protocol, addr)\nif err != nil {\n  if strings.Contains(err.Error(), \"unknown vtctld client protocol\") {\n    return fmt.Errorf(\"check --vtctld_grpc_protocol and grpcvtctldclient import: %w\", err)\n  }\n  return err\n}","preventionTips":["Validate the protocol flag in PreRunE before calling New","Blank-import grpcvtctldclient wherever vtctldclient is used","Keep protocol strings in one shared constant to avoid typos"],"tags":["go","vtctld","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"}