{"record":{"id":"607f030206a71211","repo":"fatedier/frp","slug":"proxy-s-is-repeated","errorCode":null,"errorMessage":"proxy [%s] is repeated","messagePattern":"proxy \\[(.+?)\\] is repeated","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nathole/controller.go","lineNumber":135,"sourceCode":"\t\t\tcount, total := c.analyzer.Clean()\n\t\t\tlog.Tracef(\"clean %d/%d nathole analysis data, cost %v\", count, total, time.Since(start))\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *Controller) ListenClient(name string, sk string, allowUsers []string) (chan string, error) {\n\tcfg := &ClientCfg{\n\t\tname:       name,\n\t\tsk:         sk,\n\t\tallowUsers: allowUsers,\n\t\tsidCh:      make(chan string),\n\t}\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tif _, ok := c.clientCfgs[name]; ok {\n\t\treturn nil, fmt.Errorf(\"proxy [%s] is repeated\", name)\n\t}\n\tc.clientCfgs[name] = cfg\n\treturn cfg.sidCh, nil\n}\n\nfunc (c *Controller) CloseClient(name string) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tdelete(c.clientCfgs, name)\n}\n\nfunc (c *Controller) GenSid() string {\n\tt := time.Now().Unix()\n\tid, _ := util.RandID()\n\treturn fmt.Sprintf(\"%d%s\", t, id)\n}\n\nfunc (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport.MessageTransporter, visitorUser string) {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/nathole/controller.go#L117-L153","documentation":"Thrown by Controller.ListenClient in pkg/nathole/controller.go when an xtcp client registers a proxy name that already exists in the controller's clientCfgs map. The nathole controller keys client configurations by proxy name, so a duplicate registration — before the previous entry is removed via CloseClient — is rejected.","triggerScenarios":"Two frpc instances (or one client reconnecting before the server cleaned up the old session) call ListenClient with the same proxy name. Also when a client reconnect loop re-registers xtcp proxies rapidly while the old connection's cleanup has not yet run.","commonSituations":"Running two clients with the same proxy name in frpc.toml pointing at the same frps; a crash-looping or frequently reconnecting client whose stale registration lingers on the server; duplicated xtcp proxy config blocks copy-pasted between clients.","solutions":["Give each xtcp proxy a unique name across all clients connecting to the same frps","If it is a reconnect artifact, wait for the server to reap the old session or restart frps to clear stale registrations","Check for accidentally duplicated proxy blocks in the client config","Ensure the client calls CloseClient / disconnects cleanly so registrations are freed"],"exampleFix":"# before (frpc.toml, two clients both have)\n[[proxies]]\nname = \"p2p\"\ntype = \"xtcp\"\n\n# after (unique per client)\n[[proxies]]\nname = \"p2p-alice\"\ntype = \"xtcp\"","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"sidCh, err := controller.ListenClient(name, sk, allowUsers)\nif err != nil && strings.Contains(err.Error(), \"is repeated\") {\n    // either reuse the existing registration or pick a new unique name\n}","preventionTips":["Give every xtcp proxy a globally unique name per frps","Clean up registrations on disconnect (CloseClient)","Avoid rapid reconnect loops that re-register before cleanup"],"tags":["go","frp","nathole","xtcp","configuration"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}