fatedier/frp · error · configmgmt.ErrApplyConfig

apply config failed: proxy %q not found in store after mutat

Error message

apply config failed: proxy %q not found in store after mutation

What it means

After a proxy mutation and successful reload, withStoreProxyMutationAndReload re-reads the proxy from the store; if GetProxy returns nil it fails with ErrApplyConfig. This is an internal consistency check — the proxy that was just written is no longer readable, meaning the store write did not stick or the store was mutated concurrently.

Source

Thrown at client/config_manager.go:411

) (v1.ProxyConfigurer, error) {
	m.svr.reloadMu.Lock()
	defer m.svr.reloadMu.Unlock()

	storeSource := m.svr.storeSource
	if storeSource == nil {
		return nil, fmt.Errorf("%w: store API is disabled", configmgmt.ErrStoreDisabled)
	}

	if err := fn(storeSource); err != nil {
		return nil, err
	}
	if err := m.svr.reloadConfigFromSourcesLocked(); err != nil {
		return nil, fmt.Errorf("%w: failed to apply config: %v", configmgmt.ErrApplyConfig, err)
	}

	persisted := storeSource.GetProxy(name)
	if persisted == nil {
		return nil, fmt.Errorf("%w: proxy %q not found in store after mutation", configmgmt.ErrApplyConfig, name)
	}
	return persisted.Clone(), nil
}

func (m *serviceConfigManager) withStoreVisitorMutationAndReload(
	name string,
	fn func(storeSource *source.StoreSource) error,
) (v1.VisitorConfigurer, error) {
	m.svr.reloadMu.Lock()
	defer m.svr.reloadMu.Unlock()

	storeSource := m.svr.storeSource
	if storeSource == nil {
		return nil, fmt.Errorf("%w: store API is disabled", configmgmt.ErrStoreDisabled)
	}

	if err := fn(storeSource); err != nil {
		return nil, err

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Retry the operation once (likely transient race)
  2. Serialize store mutations with a lock in your automation so only one writer runs at a time
  3. Verify only one frpc process uses the store path
  4. Check store file health/permissions on disk
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Rare race: another writer (a second admin API call, or an external process touching the store file at common.store.path) removes/renames the proxy between the mutation and the read-back; or the store backend silently dropped the write.

Common situations: Concurrent API calls from multiple automation tools; store file on flaky storage; two frpc instances pointed at the same store file.

Related errors


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