apache/flink · error · RuntimeException

Could not find a free permitted port on the machine.

Error message

Could not find a free permitted port on the machine.

What it means

NetUtils.getAvailablePortAddress (free-port allocation) probes candidate ports and guards each with a FileLock so concurrent Flink processes do not grab the same port; if every candidate is either unbindable or already file-locked, it gives up with this RuntimeException. Exhaustion usually means the environment restricts bindable ports or many JVMs are competing. It is a startup-time failure, not a data-path one.

Source

Thrown at flink-core/src/main/java/org/apache/flink/util/NetUtils.java:206

     * @return A non-occupied port.
     */
    public static Port getAvailablePort() {
        for (int i = 0; i < 50; i++) {
            try (ServerSocket serverSocket = new ServerSocket(0)) {
                int port = serverSocket.getLocalPort();
                if (port != 0) {
                    FileLock fileLock = new FileLock(NetUtils.class.getName() + port);
                    if (fileLock.tryLock()) {
                        return new Port(port, fileLock);
                    } else {
                        fileLock.unlockAndDestroy();
                    }
                }
            } catch (IOException ignored) {
            }
        }

        throw new RuntimeException("Could not find a free permitted port on the machine.");
    }

    // ------------------------------------------------------------------------
    //  Encoding of IP addresses for URLs
    // ------------------------------------------------------------------------

    /**
     * Returns an address in a normalized format for Pekko. When an IPv6 address is specified, it
     * normalizes the IPv6 address to avoid complications with the exact URL match policy of Pekko.
     *
     * @param host The hostname, IPv4 or IPv6 address
     * @return host which will be normalized if it is an IPv6 address
     */
    public static String unresolvedHostToNormalizedString(String host) {
        // Return loopback interface address if host is null
        // This represents the behavior of {@code InetAddress.getByName } and RFC 3330
        if (host == null) {
            host = InetAddress.getLoopbackAddress().getHostAddress();

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Widen or change the port range configuration so allocation has candidates to try.
  2. Clean stale lock files left by killed processes from the temp directory (FileLock names are NetUtils-classname + port).
  3. Reduce the number of concurrently starting Flink processes on the host.
  4. If binding is denied by the environment, run where bind(0) or the configured range is permitted.

Example fix

// before
// e.g. tests all using range 40000-40010 on a busy CI host

// after
// let the OS pick, or use a wider range
NetUtils.Port p = NetUtils.getAvailablePortAddress(); // port 0 => OS-assigned
Defensive patterns

Strategy: retry

Try / catch

catch (RuntimeException e) { if (e.getMessage().contains("free permitted port")) { /* clean stale locks in tmpdir, widen range, retry once with a different range */ } }

Prevention

When it happens

Trigger: A configured port range whose ports are all taken or below the ephemeral range; dozens of parallel Flink test JVMs on one CI host leaving stale FileLocks in java.io.tmpdir; security policy preventing binding so the socket attempt always fails.

Common situations: CI machines running many tests in parallel; leftover lock files in /tmp after killed JVMs; Docker/Kubernetes network policies blocking binds; a copied port range config that does not fit the target host.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/4e09a000779f5ef2. Report an issue: GitHub.