fatedier/frp · error

invalid proxy type: %s, support types: %v

Error message

invalid proxy type: %s, support types: %v

What it means

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.

Source

Thrown at pkg/ssh/server.go:276

}

func (s *TunnelServer) parseClientAndProxyConfigurer(_ *tcpipForward, extraPayload string) (*v1.ClientCommonConfig, v1.ProxyConfigurer, string, error) {
	helpMessage := ""
	cmd := &cobra.Command{
		Use:   "ssh v0@{address} [command]",
		Short: "ssh v0@{address} [command]",
		Run:   func(*cobra.Command, []string) {},
	}
	cmd.SetGlobalNormalizationFunc(config.WordSepNormalizeFunc)

	args := strings.Split(extraPayload, " ")
	if len(args) < 1 {
		return nil, nil, helpMessage, fmt.Errorf("invalid extra payload")
	}
	proxyType := strings.TrimSpace(args[0])
	supportTypes := []string{"tcp", "http", "https", "tcpmux", "stcp"}
	if !slices.Contains(supportTypes, proxyType) {
		return nil, nil, helpMessage, fmt.Errorf("invalid proxy type: %s, support types: %v", proxyType, supportTypes)
	}
	pc := v1.NewProxyConfigurerByType(v1.ProxyType(proxyType))
	if pc == nil {
		return nil, nil, helpMessage, fmt.Errorf("new proxy configurer error")
	}
	config.RegisterProxyFlags(cmd, pc, config.WithSSHMode())

	clientCfg := v1.ClientCommonConfig{}
	config.RegisterClientCommonConfigFlags(cmd, &clientCfg, config.WithSSHMode())

	cmd.InitDefaultHelpCmd()
	if err := cmd.ParseFlags(args); err != nil {
		if errors.Is(err, flag.ErrHelp) {
			helpMessage = cmd.UsageString()
		}
		return nil, nil, helpMessage, err
	}
	// if name is not set, generate a random one

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Start the command with a supported type: tcp, http, https, tcpmux, or stcp.
  2. For udp/xtcp/sudp, use the regular frpc client with a config file — the SSH gateway only exposes the five listed types.
  3. Re-run with the exact message shown in your SSH session; it prints the allowed list.

Example fix

# before
ssh v0@frps "udp 127.0.0.1:53"

# after
ssh v0@frps "tcp 127.0.0.1:53 --remotePort 6000"
Defensive patterns

Strategy: validation

Validate before calling

func ValidateSSHProxyType(payload string) error {
    t := strings.TrimSpace(strings.SplitN(payload, " ", 2)[0])
    switch t {
    case "tcp", "http", "https", "tcpmux", "stcp":
        return nil
    }
    return fmt.Errorf("invalid proxy type %q; supported: tcp, http, https, tcpmux, stcp", t)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/74afef139bf29e41. Report an issue: GitHub.