Skip to content

0.24.0: host silently drops packets to a new guest on ~15% of boots (guest-to-host still works) #213

Closed

Description

@icaevan

Summary: since upgrading to softnet 0.24.0, about 12–16% of VM boots come up with the host unable to reach the guest. The guest boots, gets its address and keeps sending traffic to the host, but every unicast packet from the host to the guest is silently dropped. SSH from the host sits in SYN_SENT until it times out. With 0.23.0 on the same machine: 0 of 842 boots over three days, and 0 of 34 since downgrading back.

Environment:

  • macOS 26.6.2 (25G83), Apple silicon
  • tart 2.37.0
  • softnet 0.24.0-b869e33 (Homebrew)
  • ephemeral CI VMs: clone, boot with --net-softnet, SSH in, run one job, delete; two concurrent VMs at most

What we observed on three failing boots (5-second sampling, read-only, no root):

  • The guest gets its /30 from softnet within about 10 s. The ARP entry and route on the host are correct: route -n get <guest> resolves to the right bridge10N, UP.
  • Guest-to-host traffic keeps arriving: the bridge's and vmenetN's input packet counters rise 2–5 packets/s for the whole failure.
  • Host-to-guest traffic never leaves. Pings, TCP SYNs to port 22, ping -b on the bridge and ping -S <gateway> all leave the bridge's and vmenetN's output packet counters unchanged. Meanwhile a healthy sibling VM on the other bridge answers pings in 0.4 ms with its counters moving.
  • No "no route", no-buffers or NECP counters moved.
  • One boot recovered on its own about 90 s in. The rest stayed unreachable for the full 300 s timeout.
  • Failures correlate with a new VM's bridge reusing the interface name of one torn down seconds earlier (e.g. a new VM inheriting bridge102 about 2 s after the previous VM on it was destroyed). Some failures also came minutes after the last teardown, so this isn't proven.

Not yet checked: whether pf or Internet Sharing NAT state holds the drop. That needs root (pfctl -s states, tcpdump -ni bridge10N during a live failure); we can add it if useful.

Workaround: downgrading to softnet 0.23.0 (shared vmnet network, macOS DHCP) stopped the failures entirely for us. We also added a boot probe that kills and retries a VM whose port 22 stays silent after its IP appears.

Possibly related: #212, about bootpd rejecting its config while a 0.24 VM runs, and the 0.24.0 networking change #209.

Activity

  1. edi-oai commented on Oct 9, 2026

    @edi-oai
    Contributor

    Hello Evan 👋

    Thank you for reporting this!

    Should be fixed by #215.

    The ~15% that you've observed also roughly corresponds to a 12.38% chance of:

    • picking the 192.168.0.0/16 pool
    • picking the third octet with three digits
    • picking the fourth octet with three digits
  2. pcshrosbree commented on Oct 12, 2026

    @pcshrosbree

    We hit the same symptom on softnet 0.24.0 and read the host's packet filter while a VM was in the failing state, before 0.24.1 was released. In case it is useful, here is the filter-level evidence. It is consistent with the diagnosis behind #215.

    Environment: macOS 27.0.1 (26A434), Apple M5 Max, Tart 2.40.1, softnet 0.24.0-b869e33 from Homebrew. The VM was started as tart run --net-softnet --net-softnet-allow <two /32 addresses outside the VM subnet> --no-graphics ..., so softnet ran with the default --vm-net-type nat and --allow set to the same two addresses. One VM was running at the time.

    The failing boot. The guest got 192.168.243.154 on a /30, with gateway 192.168.243.153 on bridge100. The guest's pings and DNS queries to the gateway showed up in tcpdump on bridge100 with no reply. The host's connection attempt to the guest's port 22 never appeared on bridge100, and the host socket sat in SYN_SENT. Traffic from the guest to one of the allowed addresses went through NAT normally: an HTTPS request completed, with both directions visible on bridge100. The host never reached the guest over SSH in the hour before our CI job timed out.

    pfctl -a com.apple.internet-sharing/network_isolation -vv -s rules during the failure (excerpt; the lo0 rules @2/@3 and the IPv6 block rule @5 are omitted):

    @0 pass quick on bridge100 inet from 192.168.243.152 to 192.168.243.152 flags any keep state
      [ Evaluations: 22188     Packets: 0         Bytes: 0           States: 0     ]
    @1 pass quick on bridge100 inet6 from fd3e:9af:2974:55a7::/64 to fd3e:9af:2974:55a7::/64 flags any keep state
      [ Evaluations: 5549      Packets: 0         Bytes: 0           States: 0     ]
    @4 block drop quick inet from <network_isolation_table_v4:1> to <network_isolation_table_v4:1>
      [ Evaluations: 22186     Packets: 5078      Bytes: 339373      States: 0     ]
    

    network_isolation_table_v4 held 192.168.243.152/30. So the IPv4 pass rule had lost its /30 and named only the network address, while the IPv6 pass rule kept its /64. IPv4 traffic within the /30 therefore fell through to @4, whose drop count kept rising while we watched.

    The failing boot and the next four, on the same host and under the same InternetSharing process, polled about every 5 seconds:

    Guest subnet Rule @0 Packets dropped by @4 First successful port-22 probe from the host
    192.168.243.152/30 (the failing boot) from 192.168.243.152 to 192.168.243.152 5,078, rising to 5,147 never
    10.165.252.68/30 from 10.165.252.68/30 to 10.165.252.68/30 0 next poll, 3 s after the first poll that saw the address
    10.101.0.164/30 from 10.101.0.164/30 to 10.101.0.164/30 0 next poll, 4 s after
    10.183.183.64/30 from 10.183.183.64/30 to 10.183.183.64/30 0 two polls later, 8 s after
    172.29.200.92/30 from 172.29.200.92/30 to 172.29.200.92/30 0 next poll, 3 s after

    Written out, the failing subnet 192.168.243.152/30 is 18 characters long; the four healthy ones are 15 or 16. That fits your explanation above: a 192.168.x.y subnet with three-digit third and fourth octets.

    Rate. Between 8 and 12 October, 31 of 264 boot attempts on this host that reached the SSH wait never completed it, about 12%. That count includes retries and excludes a deliberate short-timeout test. It is close to your 12.38% estimate. Most of the 31 were cut off by our 120 s boot timeout and retried on a fresh VM. Up to our last check of the installed version (0.24.0, on 10 October), it was 5 of 80. We read the filter rules for only one of the 31, so the others are not confirmed to be this rule.

    No action requested. The rules are owned by macOS's Internet Sharing (com.apple.internet-sharing), and its log shows it committing filter rules through pfd when it set up the next network, so the dropped prefix looks like a macOS bug. We are considering a Feedback Assistant report. If you have already filed one, an FB number would let us reference it.

    Note

    This comment was prepared with AI assistance (Anthropic Claude, checked by OpenAI Codex) at my request. I reviewed it and the captures before posting.

  3. pcshrosbree commented on Oct 12, 2026

    @pcshrosbree

    Filed with Apple as FB25165722, with the two sysdiagnoses taken while the rule was live.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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