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

  1. Check mgr.StoreEnabled() (or GET the admin API) before issuing store mutations
  2. Enable the store/webServer feature in the frpc startup configuration so SetStoreSource runs
  3. Fall back to file-based config: WriteConfigFile + ReloadFromFile
  4. 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

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


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/7252b520796cae2f. Report an issue: GitHub.