fatedier/frp · error
acquire port %d error: %v
Error message
acquire port %d error: %v
What it means
UDPProxy.Run asks the server's UDPPortManager to Acquire the requested remote port; failure is wrapped as "acquire port %d error". Acquire fails when the port is already bound, not allowed by allowPorts, or no port is available for allocation. The deferred Release unwinds the partial allocation, so the proxy start aborts cleanly.
Source
Thrown at server/proxy/udp.go:82
}
func NewUDPProxy(baseProxy *BaseProxy) Proxy {
unwrapped, ok := baseProxy.GetConfigurer().(*v1.UDPProxyConfig)
if !ok {
return nil
}
baseProxy.usedPortsNum = 1
return &UDPProxy{
BaseProxy: baseProxy,
cfg: unwrapped,
}
}
func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
xl := pxy.xl
pxy.realBindPort, err = pxy.rc.UDPPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
if err != nil {
return "", fmt.Errorf("acquire port %d error: %v", pxy.cfg.RemotePort, err)
}
defer func() {
if err != nil {
pxy.rc.UDPPortManager.Release(pxy.realBindPort)
}
}()
remoteAddr = fmt.Sprintf(":%d", pxy.realBindPort)
pxy.cfg.RemotePort = pxy.realBindPort
addr, errRet := net.ResolveUDPAddr("udp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realBindPort)))
if errRet != nil {
err = errRet
return
}
udpConn, errRet := net.ListenUDP("udp", addr)
if errRet != nil {
err = errRet
xl.Warnf("listen udp port error: %v", err)View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Pick a different, unoccupied remotePort or set remotePort = 0 to let frps allocate a free one
- Check frps allowPorts and move the port inside the permitted range
- On the server, verify nothing else binds that UDP port (ss -uln) and that the previous proxy using it is gone
Example fix
# before [[proxies]] type = "udp" remotePort = 6000 # taken # after [[proxies]] type = "udp" remotePort = 0 # frps picks a free UDP port
Defensive patterns
Strategy: validation
Validate before calling
// Before starting, check the UDP port is free when a fixed remotePort is set.
if cfg.RemotePort != 0 {
if c, err := net.ListenPacket("udp", fmt.Sprintf(":%d", cfg.RemotePort)); err != nil {
return fmt.Errorf("remotePort %d unavailable: %w", cfg.RemotePort, err)
} else { c.Close() }
} Try / catch
if _, err := pxy.Run(); err != nil && strings.Contains(err.Error(), "acquire port") {
// release-and-retry once with remotePort = 0 for dynamic allocation
} Prevention
- Prefer remotePort = 0 for UDP unless a fixed port is required
- Keep a single inventory of allocated ports across all frpc configs pointing at one frps
- Cross-check server allowPorts before hard-coding a remotePort
When it happens
Trigger: remotePort already used by another UDP proxy or another process on the server; remotePort outside the server's allowPorts range; remotePort = 0 (random allocation) but the allowed range is exhausted.
Common situations: Hard-coding the same remotePort in several client configs; the port occupied by an unrelated service on the host; firewall/allowPorts policy on frps that the client config ignores.
Related errors
- udp write closed listener
- channel for udp listener closed
- create server listener error, %v
- listen on kcp udp address %s error: %v
- listen on quic udp address %s error: %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/fcc3b993005be157.
Report an issue: GitHub.