libnyanpasu/clash-nyanpasu · critical
Can't find an open port
Error message
Can't find an open port
What it means
get_clash_external_port resolves the external controller port. With the AllowFallback strategy, if the configured port is occupied it calls port_scanner::request_open_port() for any free port; if the scanner finds none, this error is thrown. It means no bindable local port could be found at all.
Solutions
- Free ports: kill stale listeners or widen the ephemeral range (sysctl net.ipv4.ip_local_port_range).
- Check firewall/security software that may block binds on all ports.
- Restart the host/network stack to clear TIME_WAIT sockets.
- Pin a known-free port or change the strategy so no fallback scan is needed.
Example fix
# before sysctl net.ipv4.ip_local_port_range # 32768 60999, exhausted # after sudo sysctl -w net.ipv4.ip_local_port_range="1024 65535"
Defensive patterns
Strategy: retry
Validate before calling
// check a bindable port exists before launch (node)
const net = require('net');
const s = net.createServer(); s.listen(0, () => { console.log('bindable'); s.close(); }); Try / catch
try {
await startCore();
} catch (e) {
if (String(e).includes("Can't find an open port")) {
retryWithBackoff(startCore, 3); // transient port exhaustion
} else throw e;
} Prevention
- Monitor ephemeral port exhaustion in long-running hosts
- Raise net.ipv4.ip_local_port_range on servers/containers
- Avoid running hundreds of listeners in the same netns
When it happens
Trigger: request_open_port() finds every candidate port bound - heavily loaded machines, containers with exhausted ephemeral port ranges, or sandboxes where bind() is denied for all ports.
Common situations: Docker/CI environments with net.ipv4.ip_local_port_range exhausted, huge TIME_WAIT socket counts, or firewall/security software blocking port binds.
Related errors
- download failed
- failed to download PAC script
- failed to download PAC script after
- failed to download PAC script, status
- failed to read PAC script content
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/cbad9de78421d7f1.
Report an issue: GitHub.
Appendix: source
Thrown at backend/tauri/src/utils/help.rs:174
pub fn get_clash_external_port(
strategy: &ExternalControllerPortStrategy,
port: u16,
) -> anyhow::Result<u16> {
match strategy {
ExternalControllerPortStrategy::Fixed => {
if !port_scanner::local_port_available(port) {
bail!("Port {} is not available", port);
}
}
ExternalControllerPortStrategy::Random | ExternalControllerPortStrategy::AllowFallback => {
if ExternalControllerPortStrategy::AllowFallback == *strategy
&& port_scanner::local_port_available(port)
{
return Ok(port);
}
let new_port = port_scanner::request_open_port()
.ok_or_else(|| anyhow!("Can't find an open port"))?;
return Ok(new_port);
}
}
Ok(port)
}
pub fn resize_tray_image(img: &[u8], scale_factor: f64) -> Result<Vec<u8>> {
let img = ImageReader::new(Cursor::new(img))
.with_guessed_format()?
.decode()?;
let width = img.width();
let height = img.height();
let src_pixels = img.into_rgba8().into_raw();
let src_image = ImageRef::new(width, height, &src_pixels, PixelType::U8x4)
.context("failed to parse image")?;
// Create container for data of destination image
let size = (32_f64 * scale_factor).round() as u32; // 32px is the base tray size as the dpi is 96View on GitHub (pinned to f7dbce2997)