fatedier/frp · error · configmgmt.ErrNotFound
not found: proxy %q
Error message
not found: proxy %q
What it means
Returned by GetStoreProxy when a store source exists but contains no proxy with the requested name (storeSource.GetProxy(name) returned nil). It wraps configmgmt.ErrNotFound, which the admin API surfaces as HTTP 404. Only proxies persisted in the config store are visible here; running-but-unstored proxies are not.
Source
Thrown at client/config_manager.go:173
if err != nil {
return nil, err
}
return storeSource.GetAllProxies()
}
func (m *serviceConfigManager) GetStoreProxy(name string) (v1.ProxyConfigurer, error) {
if name == "" {
return nil, fmt.Errorf("%w: proxy name is required", configmgmt.ErrInvalidArgument)
}
storeSource, err := m.storeSourceOrError()
if err != nil {
return nil, err
}
cfg := storeSource.GetProxy(name)
if cfg == nil {
return nil, fmt.Errorf("%w: proxy %q", configmgmt.ErrNotFound, name)
}
return cfg, nil
}
func (m *serviceConfigManager) CreateStoreProxy(cfg v1.ProxyConfigurer) (v1.ProxyConfigurer, error) {
if err := m.validateStoreProxyConfigurer(cfg); err != nil {
return nil, fmt.Errorf("%w: validation error: %v", configmgmt.ErrInvalidArgument, err)
}
name := cfg.GetBaseConfig().Name
persisted, err := m.withStoreProxyMutationAndReload(name, func(storeSource *source.StoreSource) error {
if err := storeSource.AddProxy(cfg); err != nil {
if errors.Is(err, source.ErrAlreadyExists) {
return fmt.Errorf("%w: %v", configmgmt.ErrConflict, err)
}
return err
}
return nilView on GitHub (pinned to 6c8a8d0a97)
Solutions
- List all stored proxies with GET /api/store/proxies and use the exact returned name.
- If the proxy should exist, create it with POST /api/store/proxies first.
- Verify you are querying the right frpc instance's admin port; each client has its own store.
Example fix
# before curl http://127.0.0.1:7400/api/store/proxies/SSH # 404 not found: proxy "SSH" # after curl http://127.0.0.1:7400/api/store/proxies | jq '.[].name' # find exact name curl http://127.0.0.1:7400/api/store/proxies/ssh
Defensive patterns
Strategy: try-catch
Validate before calling
// Check existence via the list endpoint first.
func exists(base, name string) bool {
resp, _ := http.Get(base + "/api/store/proxies")
defer resp.Body.Close()
var list []struct{ Name string }
json.NewDecoder(resp.Body).Decode(&list)
for _, p := range list { if p.Name == name { return true } }
return false
} Try / catch
cfg, err := mgr.GetStoreProxy(name)
if err != nil {
if errors.Is(err, configmgmt.ErrNotFound) {
// handle absent proxy: create it or report cleanly
}
return err
} Prevention
- Use exact names from list endpoints; proxy names are case-sensitive
- Remember file-defined proxies may not appear in the store API
When it happens
Trigger: GET /api/store/proxies/{name} for a name that was never created via POST /api/store/proxies, was deleted, or differs in case/spelling from the stored name. Also when querying a proxy defined in the static config file while the store source tracks only API-created entries, depending on how the store source is backed.
Common situations: Case mismatch (MyProxy vs myproxy); assuming file-defined proxies are in the store; a name copied from the frps dashboard that differs from the frpc-side proxy name; checking existence right after deletion.
Related errors
- not found: %v
- invalid argument: proxy name is required
- invalid argument: validation error: %v
- conflict: %v
- invalid argument: invalid proxy config: type is required
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/65b1f5f34b1d7d36.
Report an issue: GitHub.