fatedier/frp · error
proxy name [%s] is duplicated
Error message
proxy name [%s] is duplicated
What it means
validateNoDuplicateNames runs after loading all proxy/visitor configurers in the new (TOML/YAML/JSON) format. Because proxies and visitors are keyed by name in maps, duplicates would silently overwrite each other; this check rejects a duplicated proxy name with 'proxy name [<name>] is duplicated' so nothing is silently dropped.
Source
Thrown at pkg/config/load.go:432
proxyCfgs := result.Proxies
visitorCfgs := result.Visitors
proxyCfgs, visitorCfgs = FilterClientConfigurers(result.Common, proxyCfgs, visitorCfgs)
proxyCfgs = CompleteProxyConfigurers(proxyCfgs)
visitorCfgs = CompleteVisitorConfigurers(visitorCfgs)
return result.Common, proxyCfgs, visitorCfgs, result.IsLegacyFormat, nil
}
// validateNoDuplicateNames rejects proxies or visitors that share a name. They are
// keyed by name in the config sources, so a duplicate would otherwise be silently
// overwritten and never started, with no error or log.
func validateNoDuplicateNames(proxies []v1.ProxyConfigurer, visitors []v1.VisitorConfigurer) error {
proxyNames := make(map[string]struct{}, len(proxies))
for _, p := range proxies {
name := p.GetBaseConfig().Name
if _, ok := proxyNames[name]; ok {
return fmt.Errorf("proxy name [%s] is duplicated", name)
}
proxyNames[name] = struct{}{}
}
visitorNames := make(map[string]struct{}, len(visitors))
for _, v := range visitors {
name := v.GetBaseConfig().Name
if _, ok := visitorNames[name]; ok {
return fmt.Errorf("visitor name [%s] is duplicated", name)
}
visitorNames[name] = struct{}{}
}
return nil
}
func CompleteProxyConfigurers(proxies []v1.ProxyConfigurer) []v1.ProxyConfigurer {
proxyCfgs := proxiesView on GitHub (pinned to 6c8a8d0a97)
Solutions
- Find the duplicate name (the message includes it) and rename one of the entries
- If the duplicate comes from an include file, remove the copy from either the main file or the include
- grep the main file plus all includes for 'name = "<dup>"' to catch cross-file collisions
Example fix
# before [[proxies]] name = "web" [[proxies]] name = "web" # after [[proxies]] name = "web-a" [[proxies]] name = "web-b"
Defensive patterns
Strategy: validation
Validate before calling
names := sets.New[string]()
for _, p := range allProxies { if names.Has(p.GetBaseConfig().Name) { return fmt.Errorf("duplicate proxy %s", p.GetBaseConfig().Name) }; names.Insert(p.GetBaseConfig().Name) } Try / catch
if err := config.LoadClientConfig(path, strict); err != nil { if strings.Contains(err.Error(), "is duplicated") { /* extract name, dedupe sources, reload */ } } Prevention
- Generate unique names with a host/service prefix
- Deduplicate across main file and includes in CI
- grep for name collisions before merge
When it happens
Trigger: Two [[proxies]] entries in frpc.toml with the same name; the same proxy defined both in the main file and again in an included file (includes are merged before this check); names differing only by whitespace that normalize to equality.
Common situations: Copying a [[proxies]] block and forgetting to change name; per-host include files that re-declare a shared base proxy; merging configs from multiple teams.
Related errors
- visitor name [%s] is duplicated
- name should not be empty
- subdomain and custom domains should not be both empty
- subdomain is not supported because this feature is not enabl
- '.' and '*' are not supported in subdomain
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/55e1acc9e5a6ff77.
Report an issue: GitHub.