fatedier/frp · error
ErrNotFound
ErrNotFound
Error message
not found
What it means
configmgmt.ErrNotFound is the frpc config-manager sentinel for absent resources. GetProxy/GetVisitor wrap it as 'not found: proxy "<name>"' when no configurer with that name is loaded, and update/delete paths wrap store errors with it when the target does not exist in the store source. The admin HTTP layer maps it to 404 (client/http/controller.go:62).
Source
Thrown at client/configmgmt/types.go:13
package configmgmt
import (
"errors"
"time"
"github.com/fatedier/frp/client/proxy"
v1 "github.com/fatedier/frp/pkg/config/v1"
)
var (
ErrInvalidArgument = errors.New("invalid argument")
ErrNotFound = errors.New("not found")
ErrConflict = errors.New("conflict")
ErrStoreDisabled = errors.New("store disabled")
ErrApplyConfig = errors.New("apply config failed")
)
type ConfigManager interface {
ReloadFromFile(strict bool) error
ReadConfigFile() (string, error)
WriteConfigFile(content []byte) error
GetProxyStatus() []*proxy.WorkingStatus
IsStoreProxyEnabled(name string) bool
StoreEnabled() bool
GetProxyConfig(name string) (v1.ProxyConfigurer, bool)
GetVisitorConfig(name string) (v1.VisitorConfigurer, bool)
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- List all proxies/visitors (GetProxyStatus or GET /api/proxy) and confirm the exact name spelling
- If the entry lives in the config file rather than the store, edit the file or reload instead of using store APIs
- Treat errors.Is(err, configmgmt.ErrNotFound) on delete as idempotent success in automation
- Check the store path still contains the expected entries when the store source is enabled
Example fix
// before
if err := mgr.DeleteProxy(ctx, "ssh"); err != nil { return err } // not found: proxy "ssh"
// after
err := mgr.DeleteProxy(ctx, "ssh")
if err != nil && errors.Is(err, configmgmt.ErrNotFound) {
return nil // already gone — idempotent delete
} else if err != nil {
return err
} Defensive patterns
Strategy: validation
Validate before calling
if _, err := mgr.GetProxy(ctx, name); err != nil {
if errors.Is(err, configmgmt.ErrNotFound) {
// name absent — create instead of update, or 404 early
}
} Try / catch
err := mgr.DeleteProxy(ctx, name)
switch {
case err == nil:
case errors.Is(err, configmgmt.ErrNotFound):
err = nil // idempotent delete
} Prevention
- List names before referencing them; copy exact spelling
- Make deletes idempotent by swallowing ErrNotFound in automation
- Remember file-defined and store-defined entries share one name namespace
When it happens
Trigger: GET /api/proxy/{name} or /api/visitor/{name} for a name that is not in the loaded config; DELETE or PUT on a store-managed proxy/visitor whose name was never created or was already deleted.
Common situations: Dashboard or automation referencing a proxy renamed or removed in the config file; deleting the same proxy twice; name casing/whitespace mismatch between URL and stored name; store file wiped or reset so previously created entries vanished.
Related errors
- ErrInvalidArgument
- ErrConflict
- ErrStoreDisabled
- invalid argument: frpc has no config file path
- HTTP ${response.status}
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/ead96751222b3405.
Report an issue: GitHub.