apache/cordova-android · error · CordovaError

Could not find an available avd port

Error message

Could not find an available avd port

What it means

emulator.get_available_port() lists started emulators (from adb devices) and scans adb's console port range 5584 down to 5554 in steps of 2 (16 ports, the adb convention emulator-5554..emulator-5584). Throws when every port in the range is already occupied by a running emulator.

Source

Thrown at lib/emulator.js:185

    return (await Adb.devices())
        .filter(id => id.startsWith('emulator-'));
};

/*
 * Gets unused port for android emulator, between 5554 and 5584
 * Returns a promise.
 */
module.exports.get_available_port = function () {
    const self = this;

    return self.list_started().then(function (emulators) {
        for (let p = 5584; p >= 5554; p -= 2) {
            if (emulators.indexOf('emulator-' + p) === -1) {
                events.emit('verbose', 'Found available port: ' + p);
                return p;
            }
        }
        throw new CordovaError('Could not find an available avd port');
    });
};

/*
 * Starts an emulator with the given ID,
 * and returns the started ID of that emulator.
 * If no boot timeout is given or the value is negative it will wait forever for
 * the emulator to boot
 *
 * Returns a promise.
 */
module.exports.start = function (emulatorId, boot_timeout) {
    const self = this;

    return Promise.resolve().then(function () {
        if (!emulatorId) {
            throw new CordovaError('No emulator ID given');
        }

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Free ports by stopping unneeded emulators: `adb -s emulator-5554 emu kill`, close emulator windows, or `pkill -f qemu-system`.
  2. If you genuinely need more than 16 concurrent emulators on one host, split them across separate adb servers (ANDROID_ADB_SERVER_PORT) or machines - the port range is fixed.
  3. Retry `cordova emulate android` once ports are free.

Example fix

# before
$ cordova emulate android
Could not find an available avd port

# after
$ adb devices | grep emulator-   # identify stale emulators
$ adb -s emulator-5554 emu kill
$ cordova emulate android
Defensive patterns

Strategy: retry

Validate before calling

const started = await emulator.list_started(); // e.g. ['emulator-5554', 'emulator-5556']
if (started.filter(a => /^emulator-\d+$/.test(a)).length >= 16) {
  throw new Error('All 16 adb emulator ports in use - stop unneeded emulators before starting another');
}

Try / catch

try {
  await emulator.start(avdId, timeout);
} catch (e) {
  if (/Could not find an available avd port/.test(e.message)) {
    await execa('adb', ['-s', (await emulator.list_started())[0], 'emu', 'kill']);
  return emulator.start(avdId, timeout); // retry once after freeing a port
  }
  throw e;
}

Prevention

When it happens

Trigger: emulator.start() -> get_available_port() when 16 or more emulators are already running (emulator-5554 through emulator-5584 all appear in `adb devices`). Typical of parallel CI farms or long-lived emulator processes that were never killed.

Common situations: CI running many concurrent Android jobs against one adb server; leaked detached emulator processes (the start() flow detaches with .unref()); local machines accumulating emulator instances over days.

Related errors


AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22). Data as JSON: /api/errors/a0616b026ff22b2a. Report an issue: GitHub.