fatedier/frp · error · ErrInvalidArgument

invalid argument: %v

Error message

invalid argument: %v

What it means

Returned by serviceConfigManager.ReloadFromFile when config.LoadClientConfigResult fails to load or parse the config file — syntax errors, unknown fields (in strict mode), unsupported file format, or missing includes. The %v carries the underlying parse error; the sentinel configmgmt.ErrInvalidArgument lets callers distinguish bad input from apply failures.

Source

Thrown at client/config_manager.go:33

	"github.com/fatedier/frp/pkg/util/log"
)

type serviceConfigManager struct {
	svr *Service
}

func newServiceConfigManager(svr *Service) configmgmt.ConfigManager {
	return &serviceConfigManager{svr: svr}
}

func (m *serviceConfigManager) ReloadFromFile(strict bool) error {
	if m.svr.configFilePath == "" {
		return fmt.Errorf("%w: frpc has no config file path", configmgmt.ErrInvalidArgument)
	}

	result, err := config.LoadClientConfigResult(m.svr.configFilePath, strict)
	if err != nil {
		return fmt.Errorf("%w: %v", configmgmt.ErrInvalidArgument, err)
	}

	proxyCfgsForValidation, visitorCfgsForValidation := config.FilterClientConfigurers(
		result.Common,
		result.Proxies,
		result.Visitors,
	)
	proxyCfgsForValidation = config.CompleteProxyConfigurers(proxyCfgsForValidation)
	visitorCfgsForValidation = config.CompleteVisitorConfigurers(visitorCfgsForValidation)

	if _, err := validation.ValidateAllClientConfig(result.Common, proxyCfgsForValidation, visitorCfgsForValidation, m.svr.unsafeFeatures); err != nil {
		return fmt.Errorf("%w: %v", configmgmt.ErrInvalidArgument, err)
	}

	if err := m.svr.UpdateConfigSource(result.Common, result.Proxies, result.Visitors); err != nil {
		return fmt.Errorf("%w: %v", configmgmt.ErrApplyConfig, err)
	}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Run frpc verify -c /etc/frp/frpc.toml — it reports the exact parse/strict error and line
  2. Fix the reported syntax error or rename the removed/renamed option
  3. Ensure all include'd files exist and are valid
  4. Only call /api/reload after verification succeeds

Example fix

# before (frpc.toml) — TOML syntax error
[common]
serverAddr = "1.2.3.4" serverPort = 7000

# after
serverAddr = "1.2.3.4"
serverPort = 7000
Defensive patterns

Strategy: validation

Validate before calling

// Pre-verify the file exactly as frpc will load it
if _, err := config.LoadClientConfigResult(path, true); err != nil {
    return fmt.Errorf("config invalid, refusing to reload: %w", err)
}

Type guard

func isInvalidArgument(err error) bool {
    return errors.Is(err, configmgmt.ErrInvalidArgument)
}

Try / catch

if err := configManager.ReloadFromFile(true); err != nil {
    if errors.Is(err, configmgmt.ErrInvalidArgument) {
        // parse error: the running service keeps the old config; fix the file and retry
    }
}

Prevention

When it happens

Trigger: Calling /api/reload after editing frpc.toml with a syntax error (unclosed bracket, bad TOML type); strict-mode reload rejecting unknown keys; a config include file referenced but missing; JSON/YAML variant with wrong structure.

Common situations: Hot-reload workflows where an operator edits the live config and reloads without verifying; CI-deployed configs with template rendering errors; upgrading frp versions where option names changed and the old key is now unknown.

Related errors


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