fatedier/frp · error
proxy name in URL must match name in body
Error message
proxy name in URL must match name in body
What it means
Returned by ProxyDefinition.Validate during an update (PUT /api/proxies/{name}) when the name in the URL path differs from the "name" field in the JSON body. frpc refuses to rename a proxy via update because the name is its identity key; both must agree.
Source
Thrown at client/http/model/proxy_definition.go:32
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 {
return nil, fmt.Errorf("exactly one proxy type block is required")
}
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Make the body's "name" identical to the name in the URL path.
- To rename a proxy, DELETE the old one and POST a new definition — updates cannot change identity.
- Add an assertion in client code that body.name == URL name before sending the PUT.
Example fix
// before
PUT /api/proxies/ssh-old
{"name": "ssh-new", "type": "tcp", ...}
// after
PUT /api/proxies/ssh-old
{"name": "ssh-old", "type": "tcp", ...} Defensive patterns
Strategy: validation
Validate before calling
func checkNameMatch(pathName string, body map[string]any) error {
name, _ := body["name"].(string)
if pathName != "" && name != pathName { return fmt.Errorf("body name %q != URL name %q", name, pathName) }
return nil
} Prevention
- Single-source the name: build both URL and body from one variable.
- Never attempt renames via PUT; implement rename as delete + create.
- Add a pre-send assertion name == pathName in API client wrappers.
When it happens
Trigger: PUT /api/proxies/old-name with body {"name": "new-name", ...}; also triggers when pathName is provided and body name is a different non-empty string. It only applies when isUpdate is true (updates), not creates.
Common situations: Client code templating the body with a new name while keeping the old URL; attempting to rename a proxy with PUT instead of delete+create; stale cached body from a previous proxy being reused for a different one.
Related errors
- visitor name in URL must match name in body
- proxy name is required
- invalid proxy type: %s
- exactly one proxy type block is required
- proxy type block %q does not match type %q
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/637e928f2dd1a4de.
Report an issue: GitHub.