fatedier/frp · error

xtcp is not supported in frps

Error message

xtcp is not supported in frps

What it means

XTCPProxy.Run refuses to start when the server's NatHoleController is nil, meaning frps is running without NAT hole-punching support. The controller is normally created at service startup, so a nil value means its creation failed or was skipped in this build/config. The xtcp proxy request from the client is rejected and the proxy closes.

Source

Thrown at server/proxy/xtcp.go:55

}

func NewXTCPProxy(baseProxy *BaseProxy) Proxy {
	unwrapped, ok := baseProxy.GetConfigurer().(*v1.XTCPProxyConfig)
	if !ok {
		return nil
	}
	return &XTCPProxy{
		BaseProxy: baseProxy,
		cfg:       unwrapped,
		closeCh:   make(chan struct{}),
	}
}

func (pxy *XTCPProxy) Run() (remoteAddr string, err error) {
	xl := pxy.xl

	if pxy.rc.NatHoleController == nil {
		err = fmt.Errorf("xtcp is not supported in frps")
		return
	}
	allowUsers := pxy.cfg.AllowUsers
	// if allowUsers is empty, only allow same user from proxy
	if len(allowUsers) == 0 {
		allowUsers = []string{pxy.GetUserInfo().User}
	}
	sidCh, err := pxy.rc.NatHoleController.ListenClient(pxy.GetName(), pxy.cfg.Secretkey, allowUsers)
	if err != nil {
		return "", err
	}
	go func() {
		for {
			select {
			case <-pxy.closeCh:
				return
			case sid := <-sidCh:
				workConn, errRet := pxy.GetWorkConnFromPool(nil, nil)

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Inspect frps startup logs for "create nat hole controller error" and fix that root cause first
  2. If NAT hole punching cannot be supported on that host, remove the xtcp proxies or switch them to type = "stcp"+"sudp" style visiting
  3. Restart frps after fixing the environment so the controller is created
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := pxy.Run(); err != nil && strings.Contains(err.Error(), "xtcp is not supported") {
    // server lacks NAT hole punching: degrade to stcp+sudp instead of retrying
}

Prevention

When it happens

Trigger: Client declares an xtcp proxy while frps failed to initialize the nathole controller at boot (see "create nat hole controller error" in server logs); an embedded/custom frps built without nathole support.

Common situations: Server logs contain an earlier nathole.NewController failure (e.g. UDP socket issues) that went unnoticed; running xtcp against a restricted container/host where the controller cannot bind; version of frps where the controller is optional.

Related errors


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