fatedier/frp · critical

create nat hole controller error, %v

Error message

create nat hole controller error, %v

What it means

The last step of frps service creation builds the NAT hole controller with nathole.NewController; failure aborts startup. Without this controller, xtcp proxies cannot work (they later fail with "xtcp is not supported in frps"), so frps chooses to fail fast instead.

Source

Thrown at server/service.go:360

		svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout)
		if err != nil {
			return nil, fmt.Errorf("create vhost httpsMuxer error, %v", err)
		}

		// Init HTTPS group controller after HTTPSMuxer is created
		svr.rc.HTTPSGroupCtl = group.NewHTTPSGroupController(svr.rc.VhostHTTPSMuxer)
	}

	// frp tls listener
	svr.tlsListener = svr.muxer.Listen(2, 1, func(data []byte) bool {
		// tls first byte can be 0x16 only when vhost https port is not same with bind port
		return int(data[0]) == netpkg.FRPTLSHeadByte || int(data[0]) == 0x16
	})

	// Create nat hole controller.
	nc, err := nathole.NewController(time.Duration(cfg.NatHoleAnalysisDataReserveHours) * time.Hour)
	if err != nil {
		return nil, fmt.Errorf("create nat hole controller error, %v", err)
	}
	svr.rc.NatHoleController = nc
	return svr, nil
}

func (svr *Service) Run(ctx context.Context) {
	ctx, cancel := context.WithCancel(ctx)
	svr.ctx = ctx
	svr.cancel = cancel

	// run dashboard web server.
	if svr.webServer != nil {
		go func() {
			log.Infof("dashboard listen on %s", svr.webServer.Address())
			if err := svr.webServer.Run(); err != nil {
				log.Warnf("dashboard server exit with error: %v", err)
			}
		}()

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Check the wrapped %v cause in the frps log to identify which resource failed
  2. Ensure the process may create UDP sockets in its environment
  3. Relax the container/SELinux constraints or move frps to a host that permits UDP
Defensive patterns

Strategy: try-catch

Try / catch

if err := newService(cfg); err != nil && strings.Contains(err.Error(), "create nat hole controller error") {
    // environment cannot support xtcp: report and fix host/container UDP policy
}

Prevention

When it happens

Trigger: nathole.NewController failing, typically because it cannot set up its UDP listeners/analysis data store on the host; restricted container or firewall environments.

Common situations: Deploying frps into containers that block UDP socket creation; hosts with strict SELinux; resource limits at startup.

Related errors


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