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

  1. Pick a different, unoccupied remotePort or set remotePort = 0 to let frps allocate a free one
  2. Check frps allowPorts and move the port inside the permitted range
  3. 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

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


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