{"record":{"id":"f597d66312d28cf6","repo":"fatedier/frp","slug":"store-disabled-store-api-is-disabled","errorCode":null,"errorMessage":"store disabled: store API is disabled","messagePattern":"store disabled: store API is disabled","errorType":"http","errorClass":"configmgmt.ErrStoreDisabled","httpStatus":404,"severity":"error","filePath":"client/config_manager.go","lineNumber":364,"sourceCode":"\t}); err != nil {\n\t\treturn err\n\t}\n\n\tlog.Infof(\"store: deleted visitor %q\", name)\n\treturn nil\n}\n\nfunc (m *serviceConfigManager) GracefulClose(d time.Duration) {\n\tm.svr.GracefulClose(d)\n}\n\nfunc (m *serviceConfigManager) storeSourceOrError() (*source.StoreSource, error) {\n\tm.svr.reloadMu.Lock()\n\tstoreSource := m.svr.storeSource\n\tm.svr.reloadMu.Unlock()\n\n\tif storeSource == nil {\n\t\treturn nil, fmt.Errorf(\"%w: store API is disabled\", configmgmt.ErrStoreDisabled)\n\t}\n\treturn storeSource, nil\n}\n\nfunc (m *serviceConfigManager) withStoreMutationAndReload(\n\tfn func(storeSource *source.StoreSource) error,\n) error {\n\tm.svr.reloadMu.Lock()\n\tdefer m.svr.reloadMu.Unlock()\n\n\tstoreSource := m.svr.storeSource\n\tif storeSource == nil {\n\t\treturn fmt.Errorf(\"%w: store API is disabled\", configmgmt.ErrStoreDisabled)\n\t}\n\n\tif err := fn(storeSource); err != nil {\n\t\treturn err\n\t}","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/client/config_manager.go#L346-L382","documentation":"storeSourceOrError returns configmgmt.ErrStoreDisabled when the running frpc has no store source attached. The store exists only if common.store.enabled is true in the client config (cmd/frpc/sub/root.go:145 creates it); otherwise svr.storeSource stays nil and every read of store state fails. Maps to HTTP 404 in the admin controller.","triggerScenarios":"Any store read API (e.g. GET /api/config/proxies, GET /api/config/visitors) called while frpc runs without [store] enabled in its config file.","commonSituations":"Enabling the admin API (webServer.port) but forgetting the store section; expecting the admin API to manage file-configured proxies; config drift between environments where store is only enabled on some hosts.","solutions":["Enable the store in frpc config: set [store] enabled = true (and optionally path)","Restart frpc so NewStoreSource is created and attached to the aggregator","If storePath creation fails at startup, fix the path/permissions — startup error 'failed to create store source' means the API stays disabled","Without a store, manage config by editing the file and calling GET /api/reload"],"exampleFix":"# frpc.toml — before\n[webServer]\nport = 7400\n\n# after\n[webServer]\nport = 7400\n\n[store]\nenabled = true\npath = \"./frpc_store.db\"","handlingStrategy":"validation","validationCode":"func storeEnabled(cfgPath string) (bool, error) {\n\tb, err := os.ReadFile(cfgPath)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn strings.Contains(string(b), \"[store]\"), nil // or parse with frp config loader\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Health-check the store API at deploy time (one GET /api/config/proxies) before running automation","Always provision frpc with [store] enabled when the admin API will manage proxies"],"tags":["frp","frpc","config-store","configuration","api"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}