fatedier/frp · error · ErrInvalidArgument
invalid argument: frpc has no config file path
Error message
invalid argument: frpc has no config file path
What it means
Returned by serviceConfigManager.ReloadFromFile when frpc has no configFilePath — frpc was started without a -c config file (e.g. via admin API-created inline config, environment-only config, or programmatic embedding) so there is no file to reload. It wraps configmgmt.ErrInvalidArgument so callers can classify it.
Source
Thrown at client/config_manager.go:28
"github.com/fatedier/frp/client/proxy"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/source"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"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)
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- If you want file-based reload, start frpc with -c /path/to/frpc.toml so configFilePath is set
- If config is API-managed, use the admin API's config endpoints to update config instead of /api/reload
- Library users: load config from a known path and construct the service with that path so reload works
Example fix
# before frpc # later: curl -X POST localhost:7400/api/reload -> error # after frpc -c /etc/frp/frpc.toml # now: curl -X POST localhost:7400/api/reload works
Defensive patterns
Strategy: type-guard
Validate before calling
// Only expose the reload endpoint when a config file backs the service
if frpcConfigFilePath == "" {
// skip/503 the /api/reload handler; manage config through the admin API instead
} Type guard
func canReloadFromFile(svc *client.Service) bool {
return svc != nil && svc.ConfigFilePath() != ""
} Try / catch
if err := configManager.ReloadFromFile(strict); err != nil {
if errors.Is(err, configmgmt.ErrInvalidArgument) && strings.Contains(err.Error(), "no config file path") {
// service was started API-configured; use API config update, not file reload
}
} Prevention
- Standardize on starting frpc with an explicit -c file path in deployments that use hot reload
- Document per deployment whether config is file-managed (reload) or API-managed (no reload)
When it happens
Trigger: Starting frpc with only env vars or a config pushed via the admin API, then calling the /api/reload endpoint; embedding frpc as a library (client.NewService) without setting configFilePath; invoking ReloadFromFile on a service constructed from parsed config objects.
Common situations: Kubernetes deployments that inject config via API and later trigger a reload; automation scripts calling the reload endpoint on API-configured instances; library users expecting reload to re-read a file that was never registered.
Related errors
- invalid argument: %v
- apply config failed: %v
- invalid argument: body can't be empty
- ErrInvalidArgument
- ErrNotFound
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/48fc529a1fa8b43f.
Report an issue: GitHub.