fatedier/frp · error
visitor name [%s] is duplicated
Error message
visitor name [%s] is duplicated
What it means
The visitor counterpart of the duplicate-name check: after aggregation, two visitors sharing one name make 'visitor name [<name>] is duplicated' fail the load, preventing the map-keyed silent overwrite that would otherwise drop one visitor.
Source
Thrown at pkg/config/load.go:441
// 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 := proxies
for _, c := range proxyCfgs {
c.Complete()
}
return proxyCfgs
}
func CompleteVisitorConfigurers(visitors []v1.VisitorConfigurer) []v1.VisitorConfigurer {
visitorCfgs := visitors
for _, c := range visitorCfgs {View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Rename one of the visitor entries sharing the name
- Search main config and all includes for the duplicated visitor name and keep a single definition
- Use a naming convention (host-service-visitor) to avoid collisions across include files
Example fix
# before [[visitors]] name = "stcp-visitor" [[visitors]] name = "stcp-visitor" # after [[visitors]] name = "stcp-visitor-a" [[visitors]] name = "stcp-visitor-b"
Defensive patterns
Strategy: validation
Validate before calling
names := sets.New[string]()
for _, v := range allVisitors { if names.Has(v.GetBaseConfig().Name) { return fmt.Errorf("duplicate visitor %s", v.GetBaseConfig().Name) }; names.Insert(v.GetBaseConfig().Name) } Try / catch
if err := config.LoadClientConfig(path, strict); err != nil { if strings.Contains(err.Error(), "visitor name") && strings.Contains(err.Error(), "duplicated") { /* rename and reload */ } } Prevention
- Namespace visitor names per host/service
- Single ownership: one team owns one include file
- Validate merged config, not just fragments
When it happens
Trigger: Two [[visitors]] entries in frpc.toml sharing one name, or the same visitor defined in the main file and again in an included file — includes are merged into one list before this check runs.
Common situations: Copy-pasted [[visitors]] blocks without renaming; visitors for the same serverName defined in both the main config and an include file; multiple operators adding visitors for the same secret service.
Related errors
- proxy name [%s] is duplicated
- name is required
- server name is required
- bind port is required
- type shouldn't be empty
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/2df393edce8762c6.
Report an issue: GitHub.