fatedier/frp · error
ErrStoreDisabled
ErrStoreDisabled
Error message
store disabled
What it means
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).
Source
Thrown at client/configmgmt/types.go:15
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)
ListStoreProxies() ([]v1.ProxyConfigurer, error)
GetStoreProxy(name string) (v1.ProxyConfigurer, error)View on GitHub (pinned to 6c8a8d0a97)
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
Example fix
// before
_, err := mgr.CreateProxy(ctx, cfg) // store disabled: store API is disabled
// after
if !mgr.StoreEnabled() {
return errors.New("config store unavailable; edit the config file and call ReloadFromFile instead")
}
_, err := mgr.CreateProxy(ctx, cfg) Defensive patterns
Strategy: validation
Validate before calling
if !mgr.StoreEnabled() {
return errors.New("store API disabled; use WriteConfigFile + ReloadFromFile")
}
// safe to call Create/Update/Delete Try / catch
err := mgr.CreateProxy(ctx, cfg)
if errors.Is(err, configmgmt.ErrStoreDisabled) {
// degrade gracefully to file-based config flow
return fileBasedApply(cfg)
} Prevention
- 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'
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ErrInvalidArgument
- ErrNotFound
- ErrConflict
- 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/7252b520796cae2f.
Report an issue: GitHub.