fatedier/frp · error · configmgmt.ErrInvalidArgument
invalid argument: validation error: %v
Error message
invalid argument: validation error: %v
What it means
Returned by CreateStoreProxy when validateStoreProxyConfigurer rejects the submitted proxy config before anything is persisted. The wrapped validation error details the actual problem (missing/invalid name, missing type, invalid port ranges, invalid plugin fields, etc.). It maps to HTTP 400 via configmgmt.ErrInvalidArgument.
Source
Thrown at client/config_manager.go:180
if name == "" {
return nil, fmt.Errorf("%w: proxy name is required", configmgmt.ErrInvalidArgument)
}
storeSource, err := m.storeSourceOrError()
if err != nil {
return nil, err
}
cfg := storeSource.GetProxy(name)
if cfg == nil {
return nil, fmt.Errorf("%w: proxy %q", configmgmt.ErrNotFound, name)
}
return cfg, nil
}
func (m *serviceConfigManager) CreateStoreProxy(cfg v1.ProxyConfigurer) (v1.ProxyConfigurer, error) {
if err := m.validateStoreProxyConfigurer(cfg); err != nil {
return nil, fmt.Errorf("%w: validation error: %v", configmgmt.ErrInvalidArgument, err)
}
name := cfg.GetBaseConfig().Name
persisted, err := m.withStoreProxyMutationAndReload(name, func(storeSource *source.StoreSource) error {
if err := storeSource.AddProxy(cfg); err != nil {
if errors.Is(err, source.ErrAlreadyExists) {
return fmt.Errorf("%w: %v", configmgmt.ErrConflict, err)
}
return err
}
return nil
})
if err != nil {
return nil, err
}
log.Infof("store: created proxy %q", name)
return persisted, nil
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Read the wrapped validation message; it names the exact field and rule that failed.
- Compare your body against a known-good proxy via GET /api/store/proxies and mirror the required fields.
- Ensure 'name' is set, 'type' is one of the supported types (tcp/udp/http/https/tcpmux/stcp/sudp/xtcp), and type-specific fields (remotePort, subdomain, locations, secretKey...) are present.
- Validate locally with the same v1 validation package before posting if you drive the Go API directly.
Example fix
# before (missing remotePort for tcp)
curl -X POST http://127.0.0.1:7400/api/store/proxies \
-d '{"type":"tcp","name":"ssh","localPort":22}'
# invalid argument: validation error: remotePort required
# after
curl -X POST http://127.0.0.1:7400/api/store/proxies \
-d '{"type":"tcp","name":"ssh","localPort":22,"remotePort":6022}' Defensive patterns
Strategy: validation
Validate before calling
// Mirror required fields before POST.
body := map[string]any{"type": "tcp", "name": name, "localPort": lp, "remotePort": rp}
if name == "" || body["type"] == "" || lp <= 0 || rp <= 0 {
return errors.New("proxy payload incomplete")
} Try / catch
if _, err := mgr.CreateStoreProxy(cfg); err != nil {
if errors.Is(err, configmgmt.ErrInvalidArgument) {
// err text carries the validation detail; fix the offending field
}
} Prevention
- Round-trip a known-good proxy from GET as your template
- Log full error text — validation messages name the exact failing field
When it happens
Trigger: POST /api/store/proxies with a body missing required fields for the proxy type (e.g. a tcp proxy without remotePort), an invalid or empty name, unsupported type value, or a plugin block that fails validation. Also triggered by structurally valid JSON whose field values violate v1 validation rules.
Common situations: Switching proxy type and forgetting type-specific fields (udp needs nothing extra, tcp needs remotePort); typos in the type discriminator; submitting YAML-shaped keys to a JSON/TOML endpoint; port values outside 1-65535 or colliding localPort semantics.
Related errors
- invalid argument: proxy name is required
- invalid argument: invalid proxy config: type is required
- invalid argument: proxy name in URL must match name in body
- not found: proxy %q
- conflict: %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/2a3b2a1aa823544a.
Report an issue: GitHub.