fatedier/frp · error

proxy [%s] is repeated

Error message

proxy [%s] is repeated

What it means

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.

Source

Thrown at pkg/nathole/controller.go:135

			count, total := c.analyzer.Clean()
			log.Tracef("clean %d/%d nathole analysis data, cost %v", count, total, time.Since(start))
		case <-ctx.Done():
			return
		}
	}
}

func (c *Controller) ListenClient(name string, sk string, allowUsers []string) (chan string, error) {
	cfg := &ClientCfg{
		name:       name,
		sk:         sk,
		allowUsers: allowUsers,
		sidCh:      make(chan string),
	}
	c.mu.Lock()
	defer c.mu.Unlock()
	if _, ok := c.clientCfgs[name]; ok {
		return nil, fmt.Errorf("proxy [%s] is repeated", name)
	}
	c.clientCfgs[name] = cfg
	return cfg.sidCh, nil
}

func (c *Controller) CloseClient(name string) {
	c.mu.Lock()
	defer c.mu.Unlock()
	delete(c.clientCfgs, name)
}

func (c *Controller) GenSid() string {
	t := time.Now().Unix()
	id, _ := util.RandID()
	return fmt.Sprintf("%d%s", t, id)
}

func (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport.MessageTransporter, visitorUser string) {

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Give each xtcp proxy a unique name across all clients connecting to the same frps
  2. If it is a reconnect artifact, wait for the server to reap the old session or restart frps to clear stale registrations
  3. Check for accidentally duplicated proxy blocks in the client config
  4. Ensure the client calls CloseClient / disconnects cleanly so registrations are freed

Example fix

# before (frpc.toml, two clients both have)
[[proxies]]
name = "p2p"
type = "xtcp"

# after (unique per client)
[[proxies]]
name = "p2p-alice"
type = "xtcp"
Defensive patterns

Strategy: validation

Try / catch

sidCh, err := controller.ListenClient(name, sk, allowUsers)
if err != nil && strings.Contains(err.Error(), "is repeated") {
    // either reuse the existing registration or pick a new unique name
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/607f030206a71211. Report an issue: GitHub.