{"record":{"id":"74afef139bf29e41","repo":"fatedier/frp","slug":"invalid-proxy-type-s-support-types-v","errorCode":null,"errorMessage":"invalid proxy type: %s, support types: %v","messagePattern":"invalid proxy type: (.+?), support types: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/ssh/server.go","lineNumber":276,"sourceCode":"}\n\nfunc (s *TunnelServer) parseClientAndProxyConfigurer(_ *tcpipForward, extraPayload string) (*v1.ClientCommonConfig, v1.ProxyConfigurer, string, error) {\n\thelpMessage := \"\"\n\tcmd := &cobra.Command{\n\t\tUse:   \"ssh v0@{address} [command]\",\n\t\tShort: \"ssh v0@{address} [command]\",\n\t\tRun:   func(*cobra.Command, []string) {},\n\t}\n\tcmd.SetGlobalNormalizationFunc(config.WordSepNormalizeFunc)\n\n\targs := strings.Split(extraPayload, \" \")\n\tif len(args) < 1 {\n\t\treturn nil, nil, helpMessage, fmt.Errorf(\"invalid extra payload\")\n\t}\n\tproxyType := strings.TrimSpace(args[0])\n\tsupportTypes := []string{\"tcp\", \"http\", \"https\", \"tcpmux\", \"stcp\"}\n\tif !slices.Contains(supportTypes, proxyType) {\n\t\treturn nil, nil, helpMessage, fmt.Errorf(\"invalid proxy type: %s, support types: %v\", proxyType, supportTypes)\n\t}\n\tpc := v1.NewProxyConfigurerByType(v1.ProxyType(proxyType))\n\tif pc == nil {\n\t\treturn nil, nil, helpMessage, fmt.Errorf(\"new proxy configurer error\")\n\t}\n\tconfig.RegisterProxyFlags(cmd, pc, config.WithSSHMode())\n\n\tclientCfg := v1.ClientCommonConfig{}\n\tconfig.RegisterClientCommonConfigFlags(cmd, &clientCfg, config.WithSSHMode())\n\n\tcmd.InitDefaultHelpCmd()\n\tif err := cmd.ParseFlags(args); err != nil {\n\t\tif errors.Is(err, flag.ErrHelp) {\n\t\t\thelpMessage = cmd.UsageString()\n\t\t}\n\t\treturn nil, nil, helpMessage, err\n\t}\n\t// if name is not set, generate a random one","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/ssh/server.go#L258-L294","documentation":"Emitted when the first whitespace-separated token of the SSH extra payload is not one of the supported SSH-tunnel proxy types: tcp, http, https, tcpmux, stcp. The message lists the offending value and the allowed set, and is written back to the client's SSH session verbatim before the server-side wrapper wraps it.","triggerScenarios":"ssh v0@host \"udp ...\", \"socks5 ...\", a misspelled type like \"tcpmux \", or leading garbage before the type token (though TrimSpace handles surrounding whitespace on the token itself).","commonSituations":"Assuming every frpc proxy type (udp, sudp, xtcp, plugins) is available over the SSH gateway; copy-pasting an frpc.ini proxy type field into the ssh command; locale/terminal mangling of the first character.","solutions":["Start the command with a supported type: tcp, http, https, tcpmux, or stcp.","For udp/xtcp/sudp, use the regular frpc client with a config file — the SSH gateway only exposes the five listed types.","Re-run with the exact message shown in your SSH session; it prints the allowed list."],"exampleFix":"# before\nssh v0@frps \"udp 127.0.0.1:53\"\n\n# after\nssh v0@frps \"tcp 127.0.0.1:53 --remotePort 6000\"","handlingStrategy":"validation","validationCode":"func ValidateSSHProxyType(payload string) error {\n    t := strings.TrimSpace(strings.SplitN(payload, \" \", 2)[0])\n    switch t {\n    case \"tcp\", \"http\", \"https\", \"tcpmux\", \"stcp\":\n        return nil\n    }\n    return fmt.Errorf(\"invalid proxy type %q; supported: tcp, http, https, tcpmux, stcp\", t)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Start every tunnel command with one of the five supported types.","Wrap ssh invocations in scripts that validate the first token.","For udp/xtcp/sudp, use regular frpc with a config file."],"tags":["ssh","validation","user-input","cli"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}