Skip to content

network_bridge=true creates macOS bridge interfaces that trigger sustained airportd high CPU via Apple SystemConfiguration/IOKit #2461

@xykong

Description

@xykong

Describe the bug

When OrbStack network_bridge=true is enabled, OrbStack creates macOS bridge interfaces (bridge100, bridge101, bridge102) backed by vmenet0/1/2. This topology repeatedly triggers an expensive Apple airportd / SystemConfiguration.framework / IOKit path and causes sustained high CPU usage in airportd (often 100%+ for long periods), with significant heat and battery drain.

This is not because OrbStack implements SCNetworkServiceGetName or IOServiceGetMatchingServices; those are Apple components. The issue is that OrbStack's direct container IP/domain bridge topology is visible to macOS as normal bridge/vmenet interfaces, and Apple's Wi-Fi service refresh path handles that topology very poorly.

Disabling OrbStack network_bridge removes the bridge interfaces and eliminates the sustained 100% airportd loop.

Environment

  • OrbStack: 2.1.3 (2010300), commit 7a3258b7336a8a47b75771e87ef7b74ba4bba8eb
  • macOS: 26.4.1 (25E253)
  • Mac model: Mac17,7, Apple M5 Max, 128 GB RAM
  • Kubernetes: disabled
  • Docker containers: multiple Compose projects
  • Original setting: network_bridge=true
  • Current workaround: network_bridge=false

Diagnostic report:

https://orbstack.dev/_admin/diag/orbstack-diagreport_2026-05-12T15-08-52.856126Z.zip

Local diagnostic report path:

/Users/xykong/.orbstack/diag/orbstack-diagreport_2026-05-12T15-08-52.856126Z.zip

What happened

With network_bridge=true, OrbStack created these host-visible interfaces:

bridge100 -> vmenet0 -> 192.168.138.0/23
bridge101 -> vmenet1 -> 192.168.107.0/24
bridge102 -> vmenet2 -> 192.168.97.0/24

airportd then entered a sustained high-CPU state:

PID    CPU   COMMAND
482    ~100% /usr/libexec/airportd

Full sample output shows the hot thread spending nearly all time in this path:

__updateWiFiNetworkServices (CoreWiFi)
  -> -[CWFSCNetworkService refreshServiceID]
    -> -[CWFSCNetworkService __updateServiceID]
      -> __SCNetworkServiceGetName (SystemConfiguration)
        -> SCNetworkServiceGetInterface (SystemConfiguration)
          -> _SCNetworkInterfaceCreateWithEntity (SystemConfiguration)
            -> findBridgeInterface / SCBridgeInterfaceCopyAll
              -> _SCNetworkInterfaceCreateWithBSDName
                -> findMatchingInterfaces
                  -> IOServiceGetMatchingServices (IOKit)
                    -> mach_msg2_trap

Representative sample counts from one incident:

__updateWiFiNetworkServices: 1470/1472 samples
__SCNetworkServiceGetName: 1367/1472 samples
SCBridgeInterfaceCopyAll / bridge interface traversal: 700+ samples
IOServiceGetMatchingServices: 572/1472 samples

This indicates airportd is repeatedly refreshing Wi-Fi network services and paying an expensive cost for bridge/vmenet enumeration.

Reproduction / evidence

  1. Start OrbStack with network_bridge=true.
  2. Run multiple Docker Compose projects so OrbStack creates multiple macOS bridges.
  3. Observe bridge interfaces on macOS:
ifconfig -l | tr ' ' '\n' | grep bridge

Result before workaround:

bridge100
bridge101
bridge102
  1. Observe airportd high CPU:
ps -eo pid,%cpu,%mem,etime,comm | awk '/\/airportd$/ {print}'
  1. Capture airportd stack:
sudo sample <airportd-pid> 3 -file airportd-stack-sample.txt
  1. Disable OrbStack bridge mode:
orb config set network_bridge false
orb stop
orb start
  1. Verify bridges disappear:
ifconfig -l | tr ' ' '\n' | grep bridge || echo "no bridge interfaces"

Result after workaround:

no bridge interfaces
  1. Verify sustained airportd 100% loop disappears. After disabling network_bridge, airportd mostly stays near 0%, with only short Wi-Fi scanning spikes.

Expected behavior

OrbStack's direct container IP/domain feature should not create a host-visible topology that can drive Apple system daemons like airportd into sustained high CPU.

Ideally OrbStack would provide one or more of:

  • a single shared host bridge instead of one bridge per Compose/Docker network,
  • an option to keep *.orb.local / container domains working without exposing every Docker network as a macOS bridge,
  • a mode that avoids macOS bridge interfaces entirely but still preserves localhost port forwarding,
  • better warnings in the UI/docs that network_bridge=true creates host-visible bridge interfaces and may trigger macOS daemon CPU/battery issues.

Actual workaround

I currently use:

orb config set network_bridge false
orb stop
orb start

This removes bridge100/101/102 and fixes the sustained airportd CPU loop, but it also disables direct access to container IPs and breaks container domains that depend on direct IP access.

Port forwarding via localhost continues to work.

Attachments / diagnostics

I can attach the following if useful:

  • OrbStack diagnostic report zip
  • airportd stack sample showing the hot path
  • before/after ifconfig output
  • before/after airportd CPU samples
  • automated monitor logs

The most important sample is the airportd stack showing:

CoreWiFi -> SystemConfiguration -> SCBridgeInterfaceCopyAll -> IOKit IOServiceGetMatchingServices

Related issue

This appears related to the class of issues described in:

That issue focuses on mDNSResponder/darkwake battery drain. This report is specifically about airportd sustained CPU while awake, with stack evidence pointing to Apple SystemConfiguration bridge/vmenet enumeration triggered by OrbStack-created bridges.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions