Skip to content

Client applies tunnel network settings once per IP routed resource instead of batching — connect takes ~0.2 s per resource with VPN icon flicker #181

Description

@Lirok228

Summary

Self-hosted NetBird. On iOS, the session reaches Connected in ~1.3 s, but for the next 10–14 s the VPN status-bar icon flickers 3–4 times and the tunnel is effectively unusable. Desktop clients (macOS/Windows) on the same account, against the same management/signal/relay, connect in 1–2 s. Not observed on Android.

The cause we measured: the client performs one tunnel network settings application per IP routed resource (~0.2 s each) instead of batching them into a single application. Domain resources are unaffected.

What the device logs show (macOS Console streaming from the iPhone)

Timeline from nesessionmanager / SpringBoard / mDNSResponder during one connect (network map with 64 IP routed resources):

  • Received a start commandstatus changed to connected in 1.3 s — this part is fine.
  • Then, for the next 14 s, tunnel network settings are applied 191 times (~13–15 applies/s). Each cycle on the tun interface: utunX: removing DNS / removing IPv4 / removing IPv6 / removing proxiessetting DNS / setting IPv4 …. IPv4 config is present in only 64 of the 191 applies — most of that window the interface has no IPv4 at all, so routed traffic fails.
  • mDNSResponder processes ~85 network-config changes per second during the window.
  • SpringBoard receives ~65 VPN state-change notifications → the status-bar VPN icon visibly flickers.

Controlled experiments (same phone, test user, varying the policy contents)

Network map contents "provider set tunnel configuration" events Churn duration
64 IP resources (subnets/hosts) 64 ~14 s
46 IP resources (single network) 47 (= 46 + 1 initial) ~11 s
11 IP resources ~2 icon redraws < 1 s
113 domain resources only no churn none — connects instantly

The effect is linear in the number of subnet/host resources: ~0.2 s of tunnel instability per resource. With a realistic enterprise network map (~50–60 subnets) every connect costs 10+ seconds of icon flicker and broken routing. Domain resources, even 113 of them, cause no churn at all — so the per-item reapply happens on the IP-route path specifically.

Also ruled out: immediate reconnect is equally slow (not extension cold start), Wi-Fi and LTE behave the same (not DNS64/IPv6), and two independent self-hosted installs behind different load balancers show identical behavior (not the control plane).

Expected behavior

All routes/DNS from the network map applied in one (or a few debounced) setTunnelNetworkSettings calls, matching the effective behavior of the desktop and Android clients.

Environment

  • Self-hosted NetBird, two identical installs (nginx and hardware LB in front) — same behavior on both
  • iOS app from the App Store, NetworkExtension bundle version 0.3.3
  • Observed on iOS 26.5.2 (primary test device), multiple iPhones in the fleet affected
  • Keycloak as IdP

Debug bundle

Uploaded from the app (Settings → Troubleshoot). Upload key: d89ee892b8bb157f842d017aa9b67b59bd879fab8c73b4dce741397cc45df89d/c150e5b8-6974-4254-ae04-13e6bc8de1df

Happy to provide more logs or test a build.

Activity

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