fatedier/frp · error
invalid proxy type: %s
Error message
invalid proxy type: %s
What it means
Returned by ProxyDefinition.Validate when the proxy definition's "type" string is not one of the eight supported proxy types (tcp, udp, http, https, tcpmux, stcp, sudp, xtcp). It is checked right after the name, so it fires even if a valid type block is present.
Source
Thrown at client/http/model/proxy_definition.go:29
Name string `json:"name"`
Type string `json:"type"`
TCP *v1.TCPProxyConfig `json:"tcp,omitempty"`
UDP *v1.UDPProxyConfig `json:"udp,omitempty"`
HTTP *v1.HTTPProxyConfig `json:"http,omitempty"`
HTTPS *v1.HTTPSProxyConfig `json:"https,omitempty"`
TCPMux *v1.TCPMuxProxyConfig `json:"tcpmux,omitempty"`
STCP *v1.STCPProxyConfig `json:"stcp,omitempty"`
SUDP *v1.SUDPProxyConfig `json:"sudp,omitempty"`
XTCP *v1.XTCPProxyConfig `json:"xtcp,omitempty"`
}
func (p *ProxyDefinition) Validate(pathName string, isUpdate bool) error {
if strings.TrimSpace(p.Name) == "" {
return fmt.Errorf("proxy name is required")
}
if !IsProxyType(p.Type) {
return fmt.Errorf("invalid proxy type: %s", p.Type)
}
if isUpdate && pathName != "" && pathName != p.Name {
return fmt.Errorf("proxy name in URL must match name in body")
}
_, blockType, blockCount := p.activeBlock()
if blockCount != 1 {
return fmt.Errorf("exactly one proxy type block is required")
}
if blockType != p.Type {
return fmt.Errorf("proxy type block %q does not match type %q", blockType, p.Type)
}
return nil
}
func (p *ProxyDefinition) ToConfigurer() (v1.ProxyConfigurer, error) {
block, _, _ := p.activeBlock()
if block == nil {View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Set "type" to one of tcp, udp, http, https, tcpmux, stcp, sudp, xtcp — all lowercase.
- Check for typos and trailing whitespace in the type field.
- If you need a newer type, upgrade frpc/frps to a version that supports it.
Example fix
// before
{"name": "ssh", "type": "TCP", "tcp": {"localPort": 22}}
// after
{"name": "ssh", "type": "tcp", "tcp": {"localPort": 22}} Defensive patterns
Strategy: validation
Validate before calling
var proxyTypes = map[string]bool{"tcp":true,"udp":true,"http":true,"https":true,"tcpmux":true,"stcp":true,"sudp":true,"xtcp":true}
func validProxyType(t string) bool { return proxyTypes[strings.ToLower(strings.TrimSpace(t))] } Type guard
func isProxyType(t string) bool {
switch t {
case "tcp", "udp", "http", "https", "tcpmux", "stcp", "sudp", "xtcp":
return true
}
return false
} Try / catch
if !isProxyType(def.Type) { return fmt.Errorf("reject before send: bad type %q", def.Type) } Prevention
- Derive the type string from the same constant used to pick the block.
- Always lowercase type values.
- Check frp docs/version for supported types before using new ones.
When it happens
Trigger: POST/PUT /api/proxies with "type": "HTTP" (wrong case), "type": "grpc", a typo like "tcpmux" instead of "tcpmux", or a missing "type" field (empty string).
Common situations: Case mismatch (frp requires lowercase type strings); using a type introduced in a newer frp version against an older frpc; renaming a type in config after an upgrade; copying a v1 config into the admin API with the wrong casing.
Related errors
- exactly one proxy type block is required
- proxy type block %q does not match type %q
- proxy name is required
- proxy name in URL must match name in body
- visitor name is required
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/a2b28fbe9762d5c6.
Report an issue: GitHub.