XTLS/Xray-core · error

failed to create UDP listener

Error message

failed to create UDP listener

What it means

Thrown in handshake5 (proxy/socks/protocol.go:208) when internet.ListenSystemPacket fails to bind the UDP socket for a UDP ASSOCIATE request. The server needs a local UDP listener (bound to the configured Address IP with port 0) to relay UDP; OS-level bind failure (permission, address unavailable, socket/port exhaustion, firewall) triggers this error.

Source

Thrown at proxy/socks/protocol.go:208

	}
	request.Address = addr
	request.Port = port

	responseAddress := s.address
	responsePort := s.port
	var tempUDPConn *TempUDPConn
	//nolint:gocritic // Use if else chain for clarity
	if request.Command == protocol.RequestCommandUDP {
		if s.config.Address != nil {
			// Use configured IP as remote address in the response to UDP Associate
			responseAddress = s.config.Address.AsAddress()
		} else {
			// Use conn.LocalAddr() IP as remote address in the response by default
			responseAddress = s.localAddress
		}
		udpHub, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{IP: responseAddress.IP(), Port: 0}, nil)
		if err != nil {
			return nil, nil, errors.New("failed to create UDP listener").Base(err)
		}
		responsePort = net.Port(udpHub.LocalAddr().(*net.UDPAddr).Port)
		expectedRemote := &gonet.UDPAddr{}
		// UDP Associate should not specify a domain as source IP
		if request.Address.Family().IsDomain() || request.Address.IP().IsUnspecified() {
			expectedRemote.IP = writer.RemoteAddr().(*net.TCPAddr).IP // unix?
		} else {
			expectedRemote.IP = request.Address.IP()
			expectedRemote.Port = int(request.Port) // 0 is allowed
		}
		tempUDPConn = NewTempUDPConn(udpHub, writer, expectedRemote)
	}
	if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil {
		common.CloseIfExists(tempUDPConn)
		return nil, nil, err
	}

	return request, tempUDPConn, nil

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the base error (address already in use / cannot assign requested address / permission denied) and fix that specific condition.
  2. Raise limits: net.ipv4.ip_local_port_range, ulimit -n / LimitNOFILE, conntrack limits on the host.
  3. If config.Address is set for the inbound, make sure that IP actually exists on a local interface, or remove it to use conn.LocalAddr().
  4. Reduce concurrent UDP sessions or add relay capacity if the node is saturated.

Example fix

# before: container/node defaults exhaust
ulimit -n 1024

# after: room for UDP listeners
ulimit -n 65535
sysctl -w net.ipv4.ip_local_port_range="10240 65535"
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight on the host: ensure a UDP socket can be bound before enabling UDP ASSOCIATE
c, err := net.ListenPacket("udp", "127.0.0.1:0")
if err != nil {
    return fmt.Errorf("UDP unavailable on host: %w", err)
}
c.Close()

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to create UDP listener") {
    // log with base cause; alert if resource exhaustion (fd/port limits)
    logError("UDP listener allocation failed: %v", err)
    return err
}

Prevention

When it happens

Trigger: UDP ASSOCIATE arrives while the OS cannot allocate a UDP socket: UDP port range exhausted (many concurrent UDP sessions), the configured Address is not assigned to the host, UDP is blocked by seccomp/container policy, or the fd limit is reached.

Common situations: High-traffic relay nodes running out of ephemeral UDP ports or file descriptors; configs that pin an "address" IP that no longer exists on the interface; hardened containers denying socket(UDP); conntrack table exhaustion.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/de8a2f1790de8f13. Report an issue: GitHub.