fatedier/frp · error

reload config from sources failed: %w

Error message

reload config from sources failed: %w

What it means

Returned by reloadConfigFromSourcesLocked when the config aggregator's Load() fails during a config reload (frpc reload / API-triggered reload). Unlike startup, frpc is already running; the reload is aborted and the existing proxies keep running with the previous configuration.

Source

Thrown at client/service.go:508

func (svr *Service) reloadConfigFromSources() error {
	svr.reloadMu.Lock()
	defer svr.reloadMu.Unlock()
	return svr.reloadConfigFromSourcesLocked()
}

func (svr *Service) reloadConfigFromSourcesLocked() error {
	aggregator := svr.aggregator
	if aggregator == nil {
		return errors.New("config aggregator is not initialized")
	}

	svr.cfgMu.RLock()
	reloadCommon := svr.reloadCommon
	svr.cfgMu.RUnlock()

	proxies, visitors, err := aggregator.Load()
	if err != nil {
		return fmt.Errorf("reload config from sources failed: %w", err)
	}

	proxies, visitors = config.FilterClientConfigurers(reloadCommon, proxies, visitors)
	proxies = config.CompleteProxyConfigurers(proxies)
	visitors = config.CompleteVisitorConfigurers(visitors)
	requirements := validation.GetClientConfigRequirements(reloadCommon, proxies, visitors)
	if svr.vnetController == nil && requirements.VirtualNet {
		return errors.New(
			"VirtualNet-dependent configuration requires a VirtualNet runtime enabled at startup; " +
				"restart frpc after configuring featureGates.VirtualNet and virtualNet.address",
		)
	}

	// Atomically replace the entire configuration
	if err := svr.UpdateAllConfigurer(proxies, visitors); err != nil {
		return err
	}
	return nil

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Check the wrapped error for the failing source and line number of the parse failure.
  2. Fix the config file syntax and run frpc verify -c frpc.toml before retrying the reload.
  3. Make edits atomically (write temp file + rename) so reload never sees a half-written file.
  4. Note the running config is unchanged — no need to restart unless you want the failed changes forced.

Example fix

# before: reload after breaking the file
# [[proxies]  (missing closing brackets)

# after: fix syntax, verify, then reload
# [[proxies]]
#   name = "ssh"
frpc verify -c frpc.toml && frpc reload -c frpc.toml
Defensive patterns

Strategy: validation

Validate before calling

// Validate before reload: parse the file exactly as frpc will
// shell: frpc verify -c frpc.toml && frpc reload -c frpc.toml

Try / catch

if err := svr.ReloadConfig(); err != nil {
    if strings.Contains(err.Error(), "reload config from sources") {
        log.Warnf("reload aborted, running with previous config: %v", err)
        // safe to keep serving; fix file and reload again
    }
}

Prevention

When it happens

Trigger: Editing a config source (file or included fragment) into an invalid state and then triggering reload; a watched file being unreadable mid-write; an include disappearing between startup and reload.

Common situations: Hot-reloading after a partial edit (editor write in progress); broken TOML introduced by sed/script automation; include files removed but still referenced.

Related errors


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