apache/incubator-seata · error · RuntimeException

no available mac found

Error message

no available mac found

What it means

When IdWorker is given no explicit workerId, it derives one from the host's MAC address (generateWorkerIdBaseOnMac). It walks NetworkInterface.getNetworkInterfaces(), skipping loopback, virtual, and interfaces without a hardware address. If every interface is skipped (or there are none), it throws RuntimeException("no available mac found").

Source

Thrown at common/src/main/java/org/apache/seata/common/util/IdWorker.java:174

    /**
     * use lowest 10 bit of available MAC as workerId
     * @return workerId
     * @throws Exception when there is no available mac found
     */
    private long generateWorkerIdBaseOnMac() throws Exception {
        Enumeration<NetworkInterface> all = NetworkInterface.getNetworkInterfaces();
        while (all.hasMoreElements()) {
            NetworkInterface networkInterface = all.nextElement();
            boolean isLoopback = networkInterface.isLoopback();
            boolean isVirtual = networkInterface.isVirtual();
            byte[] mac = networkInterface.getHardwareAddress();
            if (isLoopback || isVirtual || mac == null) {
                continue;
            }
            return ((mac[4] & 0B11) << 8) | (mac[5] & 0xFF);
        }
        throw new RuntimeException("no available mac found");
    }

    /**
     * randomly generate one as workerId
     * @return workerId
     */
    private long generateRandomWorkerId() {
        return new Random().nextInt(maxWorkerId + 1);
    }
}

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Supply an explicit in-range workerId (0-1023) instead of relying on MAC auto-generation
  2. Ensure the container/host has a non-loopback, non-virtual network interface (e.g. run with a normal bridge network, not --network none)
  3. Run with a JVM policy that permits NetworkInterface access

Example fix

// before
IdWorker worker = new IdWorker(null); // auto -> may throw 'no available mac found' in containers

// after
IdWorker worker = new IdWorker(Integer.getInteger("worker.id", 0));
Defensive patterns

Strategy: fallback

Validate before calling

boolean hasMac = Collections.list(NetworkInterface.getNetworkInterfaces()).stream().anyMatch(ni -> { try { return !ni.isLoopback() && !ni.isVirtual() && ni.getHardwareAddress() != null; } catch (SocketException e) { return false; } });
if (!hasMac) workerId = explicitOrRandomId;

Try / catch

try { idWorker = new IdWorker(null); } catch (RuntimeException e) { idWorker = new IdWorker(configuredWorkerId); }

Prevention

When it happens

Trigger: Running on a host or container with only lo (loopback), virtual interfaces (veth, docker0 without a MAC), or interfaces whose getHardwareAddress() returns null — common in minimal Docker images and some CI environments — while workerId is left null/auto.

Common situations: Slim/minimal Docker containers (no eth0), sandboxed CI runners, or hosts where Java SecurityManager permissions block network interface enumeration (which surfaces as the enclosing Exception).

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/390fd1d8aec1e787. Report an issue: GitHub.