fatedier/frp · warning
no proxy status found
Error message
no proxy status found
What it means
Returned by Client.GetProxyStatus when /api/status parsed fine but no proxy with the requested name exists in any status group. It means the admin API is healthy but the named proxy is not registered (yet) — typically not yet started, already closed, or the name is wrong.
Source
Thrown at pkg/sdk/client/client.go:55
if err != nil {
return nil, err
}
content, err := c.do(req)
if err != nil {
return nil, err
}
allStatus := make(model.StatusResp)
if err = json.Unmarshal([]byte(content), &allStatus); err != nil {
return nil, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(content))
}
for _, pss := range allStatus {
for _, ps := range pss {
if ps.Name == name {
return &ps, nil
}
}
}
return nil, fmt.Errorf("no proxy status found")
}
func (c *Client) GetAllProxyStatus(ctx context.Context) (model.StatusResp, error) {
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+c.address+"/api/status", nil)
if err != nil {
return nil, err
}
content, err := c.do(req)
if err != nil {
return nil, err
}
allStatus := make(model.StatusResp)
if err = json.Unmarshal([]byte(content), &allStatus); err != nil {
return nil, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(content))
}
return allStatus, nil
}
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- List all statuses with GetAllProxyStatus and compare actual names with the requested one.
- If polling at startup, retry with backoff until the proxy registers or a timeout expires.
- Check the proxy exists in frpc.toml and that its name matches exactly (names are case-sensitive).
Example fix
// before
status, err := client.GetProxyStatus(ctx, "web")
if err != nil { return err } // fails during frpc startup
// after
var status *model.ProxyStatusResp
err = retryWithBackoff(ctx, 5*time.Second, func() error {
var e error
status, e = client.GetProxyStatus(ctx, "web")
return e
}) Defensive patterns
Strategy: retry
Validate before calling
// confirm the proxy name exists before targeted queries
all, err := client.GetAllProxyStatus(ctx)
if err != nil { return err }
for _, group := range all {
for _, ps := range group {
if ps.Name == name { /* exists */ }
}
} Try / catch
var st *model.ProxyStatusResp
err := backoff Retry(ctx, func() error {
var e error
st, e = client.GetProxyStatus(ctx, "web")
return e // retry while proxy not yet registered
}) Prevention
- Poll with backoff after frpc start instead of a single immediate query.
- Derive the queried name from the same config source frpc loads to avoid drift.
When it happens
Trigger: Querying a proxy by name before frpc finished establishing it; after the proxy exited or failed to start; using a name that differs from the config (case, prefix, or renamed proxy).
Common situations: Polling loops racing against frpc startup; typos in the proxy name; querying after stop/reload removed the proxy; health checks referencing an old name after config refactor.
Related errors
- unmarshal http response error: %s
- api status code [%d]
- ps.Err
- no route found
- do http request error code: %d
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/0b540fa9db72ba23.
Report an issue: GitHub.