laurent22/joplin · error · Error
All potential ports are in use or not available.
Error message
All potential ports are in use or not available.
What it means
Thrown by ClipperServer.findAvailablePort() after 10000 iterations of randomClipperPort each calling tcp-port-used.check. If every candidate port is reported in use, the clipper server cannot bind and the API is unreachable. startPort seeds the range per environment (dev vs prod).
Source
Thrown at packages/lib/ClipperServer.ts:109
if (this.port_ === v) return;
this.port_ = v;
this.dispatch({
type: 'CLIPPER_SERVER_SET',
port: v,
});
}
public async findAvailablePort(): Promise<number> {
const tcpPortUsed = require('tcp-port-used');
let state = null;
for (let i = 0; i < 10000; i++) {
state = randomClipperPort(state, Setting.value('env'));
const inUse = await tcpPortUsed.check(state.port);
if (!inUse) return state.port;
}
throw new Error('All potential ports are in use or not available.');
}
public async isRunning() {
const tcpPortUsed = require('tcp-port-used');
const port = Setting.value('api.port') ? Setting.value('api.port') : startPort(Setting.value('env'));
const inUse = await tcpPortUsed.check(port);
return inUse ? port : 0;
}
public async start() {
if (!this.enabled()) throw new Error('Cannot start clipper server because it is disabled');
this.setPort(null);
this.setStartState(StartState.Starting);
const settingPort = Setting.value('api.port');
View on GitHub (pinned to 2654b33620)
Solutions
- Free up ports: close other Joplin instances and check `lsof -i` / `netstat` for listeners in the clipper port range.
- Restart the machine if ephemeral ports are exhausted (TIME_WAIT buildup).
- Disable any security software that reserves ephemeral ranges and retry.
- If persistent, file an issue — tcp-port-used may be misreporting on your platform.
Example fix
// before: findAvailablePort() loops forever then throws // after (manual workaround) // 1. lsof -i :41184 (or the configured clipper port range) // 2. kill the conflicting process, then retry starting the clipper server
Defensive patterns
Strategy: retry
Validate before calling
// Probe a specific candidate port before relying on findAvailablePort.
const tcpPortUsed = require('tcp-port-used');
const isFree = async (port) => !(await tcpPortUsed.check(port)); Type guard
const isPortNumber = (p) => Number.isInteger(p) && p > 0 && p < 65536;
Try / catch
try { await clipperServer.findAvailablePort(); }
catch (e) { if (/All potential ports are in use/.test(e.message)) { /* free ports or report to user; do not blind-retry */ } else throw e; } Prevention
- Avoid running many listeners concurrently on the same host; close clipper servers you no longer need.
- If the issue persists, suspect false positives from tcp-port-used on your OS and report it rather than raising the loop ceiling.
When it happens
Trigger: findAvailablePort() loops 10000 times, each tcpPortUsed.check(state.port) returns true, exhausting the search space.
Common situations: Heavily loaded machine with many listeners; firewall/security software holding ephemeral ports; another Joplin instance already running; tcp-port-used falsely reporting in use due to permission issues.
Related errors
- Could not check for updates. The server rate limit has been
- Could not check for updates. Please try again later (Error $
- Could not download from ${modelUrl}: Error ${response.status
- fetchBlob: ${method} ${url}: ${error.toString()}
- uploadBlob: ${method} ${url}: ${error.toString()}
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/921a6e98ea8e1231.
Report an issue: GitHub.