macOS SecureNetwork Suite › WARP: no internet
Cloudflare WARP connected but no internet on a Mac
The Wi-Fi icon says you are connected, Cloudflare WARP is switched on (often stuck on Connecting), and nothing loads. This page explains why WARP can leave a Mac in that state, how to tell it apart from an ISP outage, and how to get back online by hand, including at a hotel login page and alongside ProtonVPN.
Why WARP leaves your Mac looking online when it is not
Two things about WARP on macOS combine to cause this.
First, WARP is built not to stay off. Its daemon, com.cloudflare.1dot1dot1dot1.macos.warp.daemon, is a LaunchDaemon with KeepAlive and RunAtLoad, and WARP is Always On. Kill the process and launchd starts it again: in testing it was back within about 9 seconds.
Second, WARP runs its own lockdown firewall, a pf anchor named com.cloudflare.warp_svc, and that firewall stays up while the tunnel is dead. When the tunnel stops working, everything except your local network is blocked until something intervenes. Your Mac still has Wi-Fi, an IP address and a router; it just cannot reach anything past it.
The tunnel usually dies in one of these ways:
- Waking from sleep. A stale tunnel after wake is the most common way the tunnel dies on a Mac.
- Changing Wi-Fi networks.
- A captive portal (hotel, airport or café login page). The tunnel carries your traffic past the portal, so you get a dead connection instead of a login page.
- A wedged daemon. It stops answering, and a normal disconnect no longer removes its firewall.
- Another VPN taking the network, such as ProtonVPN, while WARP is only disconnected. See WARP and ProtonVPN.
Is it WARP or your internet provider?
A WARP that is up or wedged leaves traces on the system: rules in the com.cloudflare.warp_svc pf anchor, a utun interface carrying the address 172.16.0.2 (visible in ifconfig output), and a State:/Network/Service/CloudflareWARP key in the system configuration store. A teardown that worked leaves none of them.
sudo pfctl -a com.cloudflare.warp_svc -sr # any rules listed = WARP's lockdown is loaded
route -n get default # which interface holds the default route
scutil --dns # which resolvers are actually liveRead the results like this:
- Wi-Fi is down, or there is no default route: not WARP. Fix the link first.
- WARP traces present, WARP stuck on Connecting or not responding, no internet: WARP's lockdown with a dead tunnel. Carry on below.
- No WARP traces and still no internet: the link, the router or the ISP. WARP is not involved.
- Addresses work but names do not resolve: a DNS problem, not a blocked network. Flush the resolver cache with
sudo killall -HUP mDNSResponderand look atscutil --dnsto see which resolver is answering.
Decide whether the internet works by testing a public IP address, not a hostname. In a browser, broken DNS and a blocked network look the same. Do not judge the link by pinging your router either: many access points drop ping.
Get back online by hand
Start with the gentlest step and escalate only if WARP's traces survive it. Tell “not WARP” (traces gone, still offline) apart from “WARP wedged” (traces survive a disconnect) before you do anything destructive.
1. Try a clean disconnect
When the daemon is healthy, a clean disconnect removes WARP's firewall.
warp-cli disconnect
sudo pfctl -a com.cloudflare.warp_svc -sr # should now list nothingAgainst a wedged daemon, warp-cli can hang rather than fail. If it does, that is your answer: go to step 2. Otherwise:
- Online, and a login page appears: you are behind a captive portal. Leave WARP off and follow the captive-portal order.
- Online: reconnect once, carefully (step 3).
- Still offline and WARP's traces are gone: not WARP. Leave WARP off and look at the link or the ISP.
- The pf rules or the
172.16.0.2utun survive the disconnect: the daemon is wedged. Go to step 2.
2. If the disconnect does not clear it: take the daemon down
Killing the process does not help, because launchd restarts it. The daemon has to be stopped and disabled first. The order that works:
- Stop the daemon with
launchctl bootoutand disable it withlaunchctl disable, both against its system-domain label,com.cloudflare.1dot1dot1dot1.macos.warp.daemon. Disabling is what stops it coming back at the next boot, so you will need to undo it later. To see whether it is still running:sudo launchctl print system/com.cloudflare.1dot1dot1dot1.macos.warp.daemonreportsstate = runningwhile it is. - Flush the
com.cloudflare.warp_svcpf anchor and its sub-anchors. - Delete the routes left on WARP's utun interface, IPv4 and IPv6. There can be hundreds: 471 on the author's test machine. If the daemon died outright, the utun is destroyed and the kernel drops its routes for you; leftover routes are mainly a wedged-daemon problem, where the interface persists.
- Remove the
State:/Network/Service/CloudflareWARPkey from the system configuration store (withscutil). - Flush the DNS cache:
sudo killall -HUP mDNSResponder. - Prove it worked: test a public IP address, then a hostname. If it still fails, flush again, then turn the network service off and on.
If you script the route deletion: netstat abbreviates classful networks. It prints 1 for 1.0.0.0/8 and 162.158 for 162.158.0.0/16, and route delete -host reads those through inet_aton as different addresses (1 becomes 0.0.0.1, 162.158 becomes 162.0.0.158). Rebuild the full network from the number of octets before passing it to route. Skipping this left 10 of 471 routes behind in testing. Also note that on macOS netstat is /usr/sbin/netstat, not /usr/bin/netstat.
3. Bring WARP back, and check it
If you disabled the daemon in step 2, re-enable it and bootstrap it again with launchctl. Then connect and confirm you are going through Cloudflare:
warp-cli --accept-tos connect
curl -s https://www.cloudflare.com/cdn-cgi/trace | grep '^warp=' # warp=onDo not connect and walk away. A connect that never completes puts you straight back in the lockdown. Wait for WARP to show Connected and check that a public IP address responds. If it does not, disconnect again and leave WARP off until the network itself is healthy.
Hotel, airport and café Wi-Fi: portal first, WARP after
A locked-down network stack cannot log in to a captive portal. Three separate layers can each stop the login page from appearing:
| Layer | Why the portal fails | What to do |
|---|---|---|
| Cloudflare WARP | The tunnel carries your traffic straight past the portal, which never sees a request to redirect. | Take WARP down first (steps 1–2 above). |
| Encrypted or fixed DNS (a DNS-over-HTTPS profile, or resolvers you set by hand) | The portal hijacks plain DNS to send you to its page. It cannot touch an encrypted query or a fixed resolver. | Use the network's own (DHCP) DNS while you log in. DNS-settings profiles and their toggles are listed under System Settings › VPN & Filters. |
| Private Wi-Fi Address set to rotate | Each reconnect can look like a new client, so the login you just completed stops applying. | Set that network's private address to Fixed if logins keep expiring. |
The order that works:
- Take WARP down.
- Let DNS come from the network.
- Open
http://captive.apple.comand log in. - Check that you are really on the internet. Do not assume it.
- Only then reconnect WARP and restore your DNS.
Reconnecting WARP before the portal has let you on puts you back where you started.
WARP and ProtonVPN at the same time
They cannot share the Mac. When ProtonVPN's WireGuard system extension takes the network, a WARP daemon that is only disconnected wedges: it stops answering its control socket, its lockdown pf anchor stays loaded, and raw internet dies. This was reproduced on 13 October 2026. A daemon that is stopped has nothing to wedge, so stop it rather than just disconnecting:
- Before connecting ProtonVPN, stop and disable the WARP daemon as in the first item of step 2. Leave your DNS alone.
- Connect ProtonVPN from its own app. ProtonVPN 6.x cannot be started from outside it:
scutil --nc starton its service returns 0 and the connection never leaves Disconnected, because its WireGuard extension only connects when the app asks. - When you disconnect ProtonVPN, re-enable WARP's daemon and reconnect as in step 3.
If both are already up and the Mac has gone dark, you are in the wedged-daemon case: go to step 2.
WARP says “Registration Missing” after an update
This applies only to WARP builds before the 2026.8 series. Since 2026.8 (verified with 2026.8.2110 on 13 October 2026) the updater keeps the registration and the app relaunches showing Connected; you need do nothing.
On earlier builds, Cloudflare's auto-updater (com.cloudflare.warp.updater) reinstalled the app and recreated /Library/Application Support/Cloudflare/warp.db. That deleted the registration, reset the mode to Warp, and dropped the app into an onboarding picker. Ignore the picker and fix it from the command line:
warp-cli --accept-tos registration new
warp-cli --accept-tos mode tunnel_only
warp-cli --accept-tos tunnel protocol set MASQUE
warp-cli --accept-tos connect
curl -s https://www.cloudflare.com/cdn-cgi/trace | grep '^warp=' # warp=onThese commands restore the setup the author tested: a free consumer registration in tunnel-only mode over MASQUE. If you ran WARP in a different mode, change the mode line. Your DNS servers survive the update. Post-quantum shows Disabled while unregistered and returns to Enabled (network policy) by itself.
If this keeps happening
Automated: warp-killswitch, part of macOS-SecureNetwork-Suite, runs the steps on this page and checks the result of each one. sudo warp-killswitch down is the full teardown (DNS goes to DHCP so a captive portal can intercept; --keep-dns leaves DNS alone). It then proves plain internet works and escalates until it does. up restores DNS exactly as it was, reconnects, waits for Connected and a raw-IP check, and rolls back to a clean disconnected state if the tunnel never comes. heal runs the disconnect-first decision procedure above on demand. A root LaunchDaemon watchdog probes raw IP every 10 seconds, runs heal after three failures with the link up, and reconnects after a wake from sleep. On a wedged daemon it took about 137 seconds end to end in testing, so allow three minutes. An xbar menu-bar item adds Tear Down, Rebuild, Heal now and Status, and stops WARP's daemon before connecting ProtonVPN. On its first test run on a Mac, 6 of 7 tests passed; the dead-tunnel test is still unverified, so heal's captive-portal and reconnect-retry branches have not been tested.
FAQ
Why does my Mac have no internet after sleep when Cloudflare WARP is on?
A stale tunnel after wake is the most common way WARP's tunnel dies on a Mac, and WARP's lockdown firewall (the pf anchor com.cloudflare.warp_svc) stays up while the tunnel is dead, so everything except your local network is blocked. Disconnect WARP first. If its firewall rules survive the disconnect, the daemon is wedged and has to be stopped and disabled before the rules can be cleared.
How do I know if it is WARP or my internet provider?
Look for WARP's traces: rules in the com.cloudflare.warp_svc pf anchor and a utun interface with the address 172.16.0.2. If they are there and WARP is stuck on Connecting, it is WARP. If they are gone and you are still offline, or you are still offline after a clean disconnect, it is the link, the router or the ISP.
Why can't I log in to hotel Wi-Fi with Cloudflare WARP on?
The tunnel carries your traffic straight past the captive portal, so the portal never sees a request to redirect and you get a dead connection instead of a login page. Encrypted or fixed DNS also stops the portal from hijacking your lookups. Take WARP down first, use the network's own DNS, log in at http://captive.apple.com, check that you are really online, and only then reconnect WARP.
Can I use Cloudflare WARP and ProtonVPN at the same time on a Mac?
No. When ProtonVPN's WireGuard extension takes the network, a WARP daemon that is merely disconnected can wedge with its lockdown firewall still loaded, and the Mac loses its internet connection. Stop and disable the WARP daemon before connecting ProtonVPN, and bring WARP back after ProtonVPN is disconnected.
WARP says Registration Missing after an update. What do I do?
This only happens on WARP builds before the 2026.8 series; current builds keep the registration across updates. On an older build, ignore the onboarding picker, create a new registration with warp-cli, set the mode and tunnel protocol again, connect, and check that the Cloudflare trace page reports warp=on.