fatedier/frp · error
parse flags from ssh client error: %v
Error message
parse flags from ssh client error: %v
What it means
Returned by the frp SSH tunnel server when the command string the client sent after connecting (the 'extra payload', e.g. "tcp 127.0.0.1:22") cannot be parsed into frpc proxy flags via the embedded cobra command. The raw parse error is also sent back to the client over the SSH channel before the wrapper error is returned, so the user usually sees the underlying reason on their terminal.
Source
Thrown at pkg/ssh/server.go:111
if err != nil {
return err
}
s.sshConn = sshConn
addr, extraPayload, err := s.waitForwardAddrAndExtraPayload(channels, requests, 3*time.Second)
if err != nil {
return err
}
clientCfg, pc, helpMessage, err := s.parseClientAndProxyConfigurer(addr, extraPayload)
if err != nil {
if errors.Is(err, flag.ErrHelp) {
s.writeToClient(helpMessage)
return nil
}
s.writeToClient(err.Error())
return fmt.Errorf("parse flags from ssh client error: %v", err)
}
if err := clientCfg.Complete(); err != nil {
s.writeToClient(fmt.Sprintf("failed to complete client config: %v", err))
return fmt.Errorf("complete client config error: %v", err)
}
if sshConn.Permissions != nil {
clientCfg.User = util.EmptyOr(sshConn.Permissions.Extensions["user"], clientCfg.User)
}
pc.Complete()
vc, err := virtual.NewClient(virtual.ClientOptions{
Common: clientCfg,
Spec: &msg.ClientSpec{
Type: "ssh-tunnel",
// If ssh does not require authentication, then the virtual client needs to authenticate through a token.
// Otherwise, once ssh authentication is passed, the virtual client does not need to authenticate again.
AlwaysAuthPass: !s.sc.NoClientAuth,
},View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Read the message written back to your SSH session — it contains the exact cobra parse error before this wrapper fires.
- Use a supported proxy type as the first token: tcp, http, https, tcpmux, or stcp.
- Run `ssh -p port v0@host -- --help` (or an invalid flag) to get the full usage string listing accepted flags.
- Quote the whole command as one argument: ssh v0@host "tcp 127.0.0.1:22 --remotePort 6000".
Example fix
# before ssh -p 7000 v0@frps "udp 127.0.0.1:53" # after ssh -p 7000 v0@frps "tcp 127.0.0.1:53 --remotePort 6000"
Defensive patterns
Strategy: validation
Validate before calling
// validate an SSH tunnel command before sending it
var supportedSSHProxyTypes = []string{"tcp", "http", "https", "tcpmux", "stcp"}
func ValidateTunnelCommand(cmd string) error {
fields := strings.Fields(cmd)
if len(fields) == 0 {
return fmt.Errorf("empty command")
}
if !slices.Contains(supportedSSHProxyTypes, fields[0]) {
return fmt.Errorf("unsupported type %q, want one of %v", fields[0], supportedSSHProxyTypes)
}
return nil
} Prevention
- Quote the whole payload as a single ssh command argument.
- Print usage (`-- --help`) when unsure which flags exist in SSH mode.
- Remember only tcp/http/https/tcpmux/stcp are exposed over the SSH gateway.
When it happens
Trigger: Calling ssh with an unknown proxy type token (e.g. `ssh v0@host "udp ..."`), passing malformed flags (--remotePort not-a-number), unknown flags not registered in SSH mode, or a payload that fails cobra's ParseFlags. Not triggered by flag.ErrHelp, which prints usage and exits cleanly.
Common situations: Users assuming all frpc proxy types work over SSH (only tcp/http/https/tcpmux/stcp do); typos in flag names; copying an frpc.ini stanza into the ssh command line; shell quoting eating the payload so it arrives empty or split incorrectly.
Related errors
- invalid proxy type: %s, support types: %v
- get addr and extra payload timeout
- invalid extra payload
- unit not support
- ps.Err
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/3449b3f38b5b4690.
Report an issue: GitHub.