{"record":{"id":"7272060c5e45edfb","repo":"fatedier/frp","slug":"listen-udp-port-s-error-v","errorCode":null,"errorMessage":"listen udp port %s error: %v","messagePattern":"listen udp port (.+?) error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/visitor/sudp.go","lineNumber":56,"sourceCode":"\tudpConn *net.UDPConn\n\treadCh  chan *msg.UDPPacket\n\tsendCh  chan *msg.UDPPacket\n\n\tcfg *v1.SUDPVisitorConfig\n}\n\n// SUDP Run start listen a udp port\nfunc (sv *SUDPVisitor) Run() (err error) {\n\txl := xlog.FromContextSafe(sv.ctx)\n\n\taddr, err := net.ResolveUDPAddr(\"udp\", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"sudp ResolveUDPAddr error: %v\", err)\n\t}\n\n\tsv.udpConn, err = net.ListenUDP(\"udp\", addr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"listen udp port %s error: %v\", addr.String(), err)\n\t}\n\n\tsv.sendCh = make(chan *msg.UDPPacket, 1024)\n\tsv.readCh = make(chan *msg.UDPPacket, 1024)\n\n\txl.Infof(\"sudp start to work, listen on %s\", addr)\n\n\tgo sv.dispatcher()\n\tgo udp.ForwardUserConn(sv.udpConn, sv.readCh, sv.sendCh, int(sv.clientCfg.UDPPacketSize))\n\n\treturn\n}\n\nfunc (sv *SUDPVisitor) dispatcher() {\n\txl := xlog.FromContextSafe(sv.ctx)\n\n\tvar (\n\t\tvisitorConn net.Conn","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/client/visitor/sudp.go#L38-L74","documentation":"Thrown by SUDPVisitor.Run when net.ListenUDP fails to bind the resolved address for the sudp visitor — the address parsed fine, but the OS refused the UDP bind. The message includes the offending address string and the OS error (e.g. 'address already in use' or 'permission denied').","triggerScenarios":"bindPort already bound by another process (another frpc visitor, a local service); binding a privileged port (<1024) as non-root; bindAddr being an IP not present on the machine; or ephemeral-port exhaustion in containers.","commonSituations":"Two visitors (or a local app and the visitor) configured with the same bindPort; running frpc unprivileged while bindPort < 1024; container missing the interface the config names.","solutions":["Pick a free bindPort: check with ss -uln / lsof -i udp:PORT.","If using a privileged port, run frpc with CAP_NET_BIND_SERVICE or switch to a port >=1024.","Make sure bindAddr exists on the host (or use 127.0.0.1/0.0.0.0).","Deduplicate port assignments across visitors and local services."],"exampleFix":"# before — port 53 already in use / privileged\n[visitors.sudp]\nbindAddr = \"0.0.0.0\"\nbindPort = 53\n\n# after\n[visitors.sudp]\nbindAddr = \"0.0.0.0\"\nbindPort = 5353","handlingStrategy":"validation","validationCode":"// Check the UDP port is free before starting frpc with a sudp visitor\naddr, _ := net.ResolveUDPAddr(\"udp\", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))\nif c, err := net.ListenUDP(\"udp\", addr); err != nil {\n    return fmt.Errorf(\"bindPort %d not available: %w\", bindPort, err)\n} else { c.Close() }","typeGuard":null,"tryCatchPattern":"if err := visitor.Run(); err != nil {\n    if strings.Contains(err.Error(), \"listen udp port\") {\n        // pick another bindPort or stop the conflicting process, then recreate visitor\n    }\n}","preventionTips":["Maintain a central port allocation list for all visitors and local services.","Avoid privileged ports unless frpc has CAP_NET_BIND_SERVICE.","Port-probe before startup in orchestration scripts."],"tags":["udp","visitor","port-binding","sudp"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}