{"record":{"id":"7252b520796cae2f","repo":"fatedier/frp","slug":"errstoredisabled","errorCode":"ErrStoreDisabled","errorMessage":"store disabled","messagePattern":"store disabled","errorType":"error_code","errorClass":null,"httpStatus":404,"severity":"error","filePath":"client/configmgmt/types.go","lineNumber":15,"sourceCode":"package configmgmt\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/fatedier/frp/client/proxy\"\n\tv1 \"github.com/fatedier/frp/pkg/config/v1\"\n)\n\nvar (\n\tErrInvalidArgument = errors.New(\"invalid argument\")\n\tErrNotFound        = errors.New(\"not found\")\n\tErrConflict        = errors.New(\"conflict\")\n\tErrStoreDisabled   = errors.New(\"store disabled\")\n\tErrApplyConfig     = errors.New(\"apply config failed\")\n)\n\ntype ConfigManager interface {\n\tReloadFromFile(strict bool) error\n\n\tReadConfigFile() (string, error)\n\tWriteConfigFile(content []byte) error\n\n\tGetProxyStatus() []*proxy.WorkingStatus\n\tIsStoreProxyEnabled(name string) bool\n\tStoreEnabled() bool\n\n\tGetProxyConfig(name string) (v1.ProxyConfigurer, bool)\n\tGetVisitorConfig(name string) (v1.VisitorConfigurer, bool)\n\n\tListStoreProxies() ([]v1.ProxyConfigurer, error)\n\tGetStoreProxy(name string) (v1.ProxyConfigurer, error)","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/client/configmgmt/types.go#L1-L33","documentation":"configmgmt.ErrStoreDisabled is returned by every store-backed manager method (Create/Update/Delete for proxies and visitors) when the store source was never attached — i.e. frpc was started without webServer store/API support. The wrapper message is 'store API is disabled'. Notably the HTTP layer maps it to 404 (grouped with ErrNotFound in client/http/controller.go:62).","triggerScenarios":"Calling CreateProxy/UpdateProxy/DeleteProxy (or the visitor equivalents, or POST/PUT/DELETE /api/proxy|visitor) on an frpc instance whose StoreEnabled() is false because SetStoreSource was never wired up at startup.","commonSituations":"Running frpc with an old startup flow or minimal flags so the store feature is not initialized; expecting a binary/plugin-embedded frpc to expose the config store when it was built without it; version skew where the caller assumes store support the running frpc does not have.","solutions":["Check mgr.StoreEnabled() (or GET the admin API) before issuing store mutations","Enable the store/webServer feature in the frpc startup configuration so SetStoreSource runs","Fall back to file-based config: WriteConfigFile + ReloadFromFile","Upgrade/align frpc to a build that includes the configmgmt store"],"exampleFix":"// before\n_, err := mgr.CreateProxy(ctx, cfg) // store disabled: store API is disabled\n\n// after\nif !mgr.StoreEnabled() {\n    return errors.New(\"config store unavailable; edit the config file and call ReloadFromFile instead\")\n}\n_, err := mgr.CreateProxy(ctx, cfg)","handlingStrategy":"validation","validationCode":"if !mgr.StoreEnabled() {\n    return errors.New(\"store API disabled; use WriteConfigFile + ReloadFromFile\")\n}\n// safe to call Create/Update/Delete","typeGuard":null,"tryCatchPattern":"err := mgr.CreateProxy(ctx, cfg)\nif errors.Is(err, configmgmt.ErrStoreDisabled) {\n    // degrade gracefully to file-based config flow\n    return fileBasedApply(cfg)\n}","preventionTips":["Gate store UI/actions on StoreEnabled() at startup","Keep a file-based fallback path in tooling that manages frpc config","Note the admin API maps this to 404 — don't confuse it with 'not found'"],"tags":["go","frpc","config-management","feature-disabled","admin-api"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}