{"record":{"id":"fad71e463a0acac4","repo":"fatedier/frp","slug":"create-nat-hole-controller-error-v","errorCode":null,"errorMessage":"create nat hole controller error, %v","messagePattern":"create nat hole controller error, (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/service.go","lineNumber":360,"sourceCode":"\t\tsvr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"create vhost httpsMuxer error, %v\", err)\n\t\t}\n\n\t\t// Init HTTPS group controller after HTTPSMuxer is created\n\t\tsvr.rc.HTTPSGroupCtl = group.NewHTTPSGroupController(svr.rc.VhostHTTPSMuxer)\n\t}\n\n\t// frp tls listener\n\tsvr.tlsListener = svr.muxer.Listen(2, 1, func(data []byte) bool {\n\t\t// tls first byte can be 0x16 only when vhost https port is not same with bind port\n\t\treturn int(data[0]) == netpkg.FRPTLSHeadByte || int(data[0]) == 0x16\n\t})\n\n\t// Create nat hole controller.\n\tnc, err := nathole.NewController(time.Duration(cfg.NatHoleAnalysisDataReserveHours) * time.Hour)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create nat hole controller error, %v\", err)\n\t}\n\tsvr.rc.NatHoleController = nc\n\treturn svr, nil\n}\n\nfunc (svr *Service) Run(ctx context.Context) {\n\tctx, cancel := context.WithCancel(ctx)\n\tsvr.ctx = ctx\n\tsvr.cancel = cancel\n\n\t// run dashboard web server.\n\tif svr.webServer != nil {\n\t\tgo func() {\n\t\t\tlog.Infof(\"dashboard listen on %s\", svr.webServer.Address())\n\t\t\tif err := svr.webServer.Run(); err != nil {\n\t\t\t\tlog.Warnf(\"dashboard server exit with error: %v\", err)\n\t\t\t}\n\t\t}()","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/server/service.go#L342-L378","documentation":"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.","triggerScenarios":"nathole.NewController failing, typically because it cannot set up its UDP listeners/analysis data store on the host; restricted container or firewall environments.","commonSituations":"Deploying frps into containers that block UDP socket creation; hosts with strict SELinux; resource limits at startup.","solutions":["Check the wrapped %v cause in the frps log to identify which resource failed","Ensure the process may create UDP sockets in its environment","Relax the container/SELinux constraints or move frps to a host that permits UDP"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := newService(cfg); err != nil && strings.Contains(err.Error(), \"create nat hole controller error\") {\n    // environment cannot support xtcp: report and fix host/container UDP policy\n}","preventionTips":["Smoke-test frps startup in the target container image before deploying xtcp clients","Ensure UDP socket creation is permitted (SELinux, seccomp profiles)","Monitor boot logs for nathole controller creation failures"],"tags":["frps","startup","nathole","xtcp"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}