Network Extension

RSS for tag

Customize and extend the core networking features of iOS, iPad OS, and macOS using Network Extension.

Posts under Network Extension tag

201 Posts

Post

Replies

Boosts

Views

Activity

Network Extension Resources
General: Forums subtopic: App & System Services > Networking DevForums tag: Network Extension Network Extension framework documentation Routing your VPN network traffic article Filtering traffic by URL sample code Filtering Network Traffic sample code TN3120 Expected use cases for Network Extension packet tunnel providers technote TN3134 Network Extension provider deployment technote TN3165 Packet Filter is not API technote Network Extension and VPN Glossary forums post Debugging a Network Extension Provider forums post Exporting a Developer ID Network Extension forums post Network Extension Framework Entitlements forums post Network Extension vs ad hoc techniques on macOS forums post Network Extension Provider Packaging forums post NWEndpoint History and Advice forums post Extra-ordinary Networking forums post Wi-Fi management: Understanding NEHotspotConfigurationErrorInternal forums post See also Networking Resources for general networking resources, including information about Wi-Fi. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
3.3k
Mar ’26
Local Push - app-push-provider
Eons ago we were approved in the older entitlement method where we had to apply an Entitlement to our provisioning profile via a dropdown. We'd basically attach "Local Push Provider (Dist)" to our profile. That broke in May of 2025 when our fastlane process could no longer automate the creation of a provisioning profile with that profile attached. We learned the future was the capabilities so we submitted a request to migrate our Local Push Provider to a capability - https://developer.apple.com/contact/request/entitlement-migration-requests/ Meanwhile a new client wanted a white-labeled iteration of our app. So a new client requested the capability of Local Push via https://developer.apple.com/contact/request/local-push-connectivity and it worked in roughly 4 weeks. Their account now has "Network Extensions (additional values)" on the identifier which grants access to app-push-provider. Our build is fully automated - everything works. So we waited on our migration request and after months passed, we submitted in October of 2025 a new entitlement request for Local Push as our submit to migrate went stale. It never arrived again. So I started a case in 2026 roughly 6 months later - 102869206062. After many escalations I've been told: I wanted to provide an update to you regarding your entitlement request. It appears that your entitlement no longer requires a request. The channel you’ve reached is actually set up to provide administrative support to Apple Developers and those enrolled in the Apple Developer Program I just wanted to follow-up with you and ask you to please request the Network Extensions Entitlement again (19627183) It seems the overarching point is Network Extensions are no longer required for approval, but it seems app-push-provider (LocalPush) is. I don't want a random forum post to be a support thread. So looking for clarity on 2 points. Can you obtain app-push-provider (network extension) without Apple approval? Is this doc out of date? https://developer.apple.com/documentation/networkextension/local-push-connectivity To use the Local Push Connectivity API, your app must have the Network Extensions Entitlement with the app-push-provider value. Request this entitlement from the Entitlement Request Page. After you receive the entitlement, apply it to both your app target and your provider extension target. tldr; ➜ Desktop security cms -D -i match_ClientApp.mobileprovision| plutil -p - | grep 'push' 0 => "app-push-provider" ➜ Desktop security cms -D -i match_OurApp.mobileprovision| plutil -p - | grep 'push' ➜ Desktop
2
0
37
4m
NEURLFilter / SimpleURLFilter: neagent fails to open URL prefilter mmap file with errno 13 Permission denied
I am testing NEURLFilter on macOS using the SimpleURLFilter sample, and I am seeing a failure from neagent while it is saving the local URL prefilter Bloom filter to its mmap file. The relevant log is: neagent +[NEBloomFilter mmapToFile:data:dataLength:numberOfBits:numberOfHashes:murmurSeed:tag:]: NEBloomFilter - failed to open mmap file /private/var/db/urlPrefilter/com.apple.networkextension.url-prefilter-data.temp.com.example.apple-samplecode.SimpleURLFilterTC3Q7MAJXF <errno 13 - Permission denied> neagent <NEAgentURLFilterExtension: 0xc8ce64280>: -[NEAgentURLFilterExtension startURLFilter]_block_invoke - Failed to save first fetch of pre-filter data Environment: macOS: 26.5.1 (25F80) Xcode: 26.5 (17F42) Platform: macOS Signing type: Apple Development (automatically manage signing) What I am doing: Build and run the containing app. Save and enable the NEURLFilterManager configuration. The URL filter provider starts. The provider's prefilter code is reached. neagent logs the mmap failure above while trying to open a temporary file under /private/var/db/urlPrefilter. Expected result: neagent should be able to create or open its system-managed URL prefilter cache / mmap file under /private/var/db/urlPrefilter, and the local Bloom filter should be loaded successfully. Actual result: neagent fails to open the temporary mmap file with errno 13 Permission denied: /private/var/db/urlPrefilter/com.apple.networkextension.url-prefilter-data.temp.<bundle/team-specific suffix> I am not manually creating, modifying, or chmod/chown-ing /private/var/db/urlPrefilter or anything inside it. The directory and its contents are entirely system-managed. The failure appears to happen inside neagent while it is handling the system-managed URL prefilter cache. The failure occurs at the mmapToFile: step while neagent saves the Bloom filter prefilter data. Directory state: drwxr-xr-x 2 root wheel 64 /private/var/db/urlPrefilter Has anyone else encountered this? Any suggestions on what could cause neagent to fail with errno 13 on its own mmap file under /private/var/db/urlPrefilter?
0
2
24
1h
how to remove hotspot-provider
I previously attempted to apply for the hotspot-provider entitlement but was rejected. I no longer require this entitlement. I need to remove the hotspot-provider permission although the Network Extensions capability is checked. However, the generated provisioning profile still includes the hotspot-provider permission, which causes error 409 when I upload the IPA file. I only need the Network Extensions entitlement. Could you please advise how to remove hotspot-provider from the provisioning profile?
1
0
54
3h
Network Extension and DoH with preresolved IPs
Howdy, I've noticed a strange behavior recently on my macos (26.5.1) when using my System Extension-hosted Network Extension with a Packet Tunnel Provider inside: let dnsSettings = NEDNSOverHTTPSSettings(servers: ["8.8.8.8", "8.8.4.4"]) dnsSettings.serverURL = URL(string: "https://dns.google/dns-query") settings.dnsSettings = dnsSettings I have always expected this block to not need any DNS resolution, since IPs for dns.google are preconfigured, however not sure it's been the case lately. I see normal DNS requests to the addresses above to :53. Once resolved, no more DNS traffic, just :443 via TUN. Is it possible that some changes were introduced in the past months that would make macos to have to resolve dns.google with regular DNS before switching over to DoH?
0
0
6
3h
A Wi-Fi Aware network adapter has appeared in macOS 27 beta.
When entering the following command in macOS 27 beta: lvbojie@Mac ~ % netstat -I nan0 1 Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll nan0* 1500 <Link#25> 66:31:00:4c:3c:b5 0 0 41 0 0 nan0* 1500 fe80::6431: fe80:19::6431:ff: 0 - 41 - - liushicong@Mac ~ % netstat -I nan0 1 The nan0 network interface is displayed. Does this indicate that macOS will support Wi-Fi Aware in the near future?
1
0
75
4h
NEFilterDataProvider activation on consumer iOS — saveToPreferences fails (code 5), .mobileconfig requires MDM
Hello, I'm developing a gambling blocker app that uses NEFilterDataProvider. My app was approved on the App Store, but the core feature doesn't work for end users. I have the content-filter-provider entitlement. Issue 1 — saveToPreferences() fails in distribution builds In dev builds (Xcode direct install), NEFilterManager.saveToPreferences() works fine — iOS shows a permission dialog and the filter is registered. In distribution builds (TestFlight/App Store), it fails immediately: NEFilterErrorDomain code 5 — Operation not permitted Console log from nehelper: "Creating a content filter configuration is only allowed through profile in production version" Issue 2 — .mobileconfig profile requires MDM Following the Console hint, I tried a .mobileconfig profile with com.apple.webcontent-filter payload (ContentFilterUUID, FilterType: Plugin, PluginBundleID). On an unsupervised consumer iPhone (iOS 18.5), installation fails: Profile Installation Failed — MDM required Question: What is the correct mechanism to activate a NEFilterDataProvider on a consumer (non-MDM) iPhone in a distribution build? Is there a specific entitlement or approval process I'm missing? (DTS Case-ID: 20087732)
8
0
416
1d
URL Filters not activating on iOS 27 beta
(Also submitted as FB23072541) iOS 27 beta 1 brings a brand new error which ends up resulting in a state of .serverSetupIncomplete: <NEPIRChecker: 0x7de6c79b60>: -[NEPIRChecker start:responseQueue:completionHandler:]_block_invoke - PIR status returned error <Error Domain=com.apple.CipherML Code=1100 "Unable to query status due to errors: Error details were logged and redacted." UserInfo={NSLocalizedDescription=Unable to query status due to errors: Error details were logged and redacted., NSUnderlyingError=0x7de712f4e0 {Error Domain=com.apple.CipherML Code=1800 "Error details were logged and redacted." UserInfo={NSLocalizedDescription=Error details were logged and redacted.}}}> <NEAgentURLFilterExtension: 0x7de6d24e60>: -[NEAgentURLFilterExtension startURLFilter]_block_invoke - Failed to startFilter <Error Domain=NEMembershipCheckerErrorDomain Code=3 "(null)"> What’s a NEMembershipChecker? Member of what? Digging deeper I found these: Failed to prefetch tokens for group 'site.kaylees.Wipr2': Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good, NSErrorFailingURLKey=https://pirissuer.kaylees.site/token-key-for-user-token, NSUnderlyingError=0x7517125a40 {Error Domain=NSPOSIXErrorDomain Code=50 "Network is down" UserInfo={NSDescription=Network is down}}, _NSURLErrorPrivacyProxyFailureKey=true, NSLocalizedDescription=The Internet connection appears to be offline.} queryStatus(for:options:) threw an error: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good, NSErrorFailingURLKey=https://pirissuer.kaylees.site/token-key-for-user-token, NSUnderlyingError=0x7517125b00 {Error Domain=NSPOSIXErrorDomain Code=50 "Network is down" UserInfo={NSDescription=Network is down}}, _NSURLErrorPrivacyProxyFailureKey=true, NSLocalizedDescription=The Internet connection appears to be offline.} The connection and the URL mentioned are fine of course, but "Network is down” now? This new problem only affects the App Store version of my app – not present if I install from Xcode. Users report that oddly, having an active VPN on the device works around this bug.
2
2
132
1d
NEAppProxyTCPFlow: How to distinguish half-close from full connection close
I'm implementing a NETransparentProxyProvider and trying to preserve the original TCP connection semantics as transparently as possible. The current API of NEAppProxyTCPFlow appears not to provide a way to distinguish between the following situations: The client has performed a half-close by calling shutdown(SHUT_WR) (i.e. closed only its write side). The client has fully closed the socket/connection. When readData(completionHandler:) returns empty data, indicating EOF, I cannot determine which of the two cases above has occurred. This creates a problem when forwarding the connection to the upstream server. Upon receiving empty data from the flow, should the corresponding server-side connection: Perform a half-close (close only the write side / send FIN)? Be fully closed? Currently, I always perform a half-close on the server-side connection. While this almost preserves the original flow semantics, it can lead to leaked connections, since the upstream connection may remain in FIN_WAIT_2 indefinitely. Is there any supported way to determine whether the originating connection was half-closed or fully closed? If not, what is the recommended approach for implementing a transparent TCP proxy that needs to accurately preserve TCP shutdown semantics? Any guidance would be appreciated.
2
1
102
2d
Kernel panics on M5 devices with network extension
Hello, We have a security solution which intercepts network traffic for inspection using a combination of Transparent Proxy Provider and Content filter. Lately we are seeing reports from the market that on M5 Macbooks and A18 Neos the system will kernel panic using our solution, even though it never happens on M1-M4 and no significant code changes were made in the mean time. All crashes seem to be related to an internal double free in the kernel: panic(cpu 0 caller 0xfffffe003bb68224): skmem_slab_free_locked: attempt to free invalid or already-freed obj 0xf2fffe29e15f2400 on skm 0xf6fffe2518aaa200 @skmem_slab.c:646 Debugger message: panic Memory ID: 0xff OS release type: User OS version: 25D2128 Kernel version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:38 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6050 Additionally, from further log inspection, before panics we find some weird kernel messages which seem to be related to some DMA operations gone wrong in the network driver on some machines: 2026-03-30 14:11:21.779124+0300 0x30f2 Default 0x0 873 0 Arc: (Network) [com.apple.network:connection] [C9.1.1.1 IPv4#e5b4bb04:443 in_progress socket-flow (satisfied (Path is satisfied), interface: en0[802.11], ipv4, ipv6, dns, uses wifi, flow divert agg: 1, LQM: good)] event: flow:start_connect @0.075s 2026-03-30 14:11:21.780015+0300 0x1894 Default 0x0 0 0 kernel: (402262746): No more valid control units, disabling flow divert 2026-03-30 14:11:21.780017+0300 0x1894 Default 0x0 0 0 kernel: (402262746): Skipped all flow divert services, disabling flow divert 2026-03-30 14:11:21.780102+0300 0x1894 Default 0x0 0 0 kernel: SK[2]: flow_entry_alloc fe "0 proc kernel_task(0)Arc nx_port 1 flow_uuid D46E230E-B826-4E0A-8C59-4C4C8BF6AA60 flags 0x14120<CONNECTED,QOS_MARKING,EXT_PORT,EXT_FLOWID> ipver=4,src=<IPv4-redacted>.49703,dst=<IPv4-redacted>.443,proto=0x06 mask=0x0000003f,hash=0x04e0a750 tp_proto=0x06" 2026-03-30 14:11:21.780194+0300 0x1894 Default 0x0 0 0 kernel: tcp connect outgoing: [<IPv4-redacted>:49703<-><IPv4-redacted>:443] interface: en0 (skipped: 0) so_gencnt: 14634 t_state: SYN_SENT process: Arc:873 SYN in/out: 0/1 bytes in/out: 0/0 pkts in/out: 0/0 rtt: 0.0 ms rttvar: 250.0 ms base_rtt: 0 ms error: 0 so_error: 0 svc/tc: 0 flow: 0x9878386f 2026-03-30 14:11:21.934431+0300 0xed Default 0x0 0 0 kernel: Hit error condition (not panicking as we're in error handler): t8110dart <private> (dart-apcie0): invalid SID 2 TTBR access: level 1 table_index 0 page_offset 0x2 2026-03-30 14:11:21.934432+0300 0xed Default 0x0 0 0 kernel: [ 73.511690]: arm_cpu_init(): cpu 6 online 2026-03-30 14:11:21.934441+0300 0xed Default 0x0 0 0 kernel: [ 73.511696]: arm_cpu_init(): cpu 9 online 2026-03-30 14:11:21.934441+0300 0xed Default 0x0 0 0 kernel: [ 73.569033]: arm_cpu_init(): cpu 6 online 2026-03-30 14:11:21.934441+0300 0xed Default 0x0 0 0 kernel: [ 73.569038]: arm_cpu_init(): cpu 9 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.577453]: arm_cpu_init(): cpu 7 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.586328]: arm_cpu_init(): cpu 5 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.586332]: arm_cpu_init(): cpu 8 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.621392]: (dart-apcie0) AppleT8110DART::_fatalException: dart-apcie0 (<ptr>): DART DART SID exception ERROR_SID_SUMMARY 0x00003000 ERROR_ADDRESS 0x0000000000009800 2026-03-30 14:11:21.934443+0300 0xed Default 0x0 0 0 kernel: [ 73.621397]: Hit error condition (not panicking as we're in error handler): 2026-03-30 14:11:21.934443+0300 0xed Default 0x0 0 0 kernel: t8110dart <ptr> (dart-apcie0): invalid SID 2 TTBR access: level 1 table_index 0 page_offset 0x2Expect a `deadbeef` in the error messages below 2026-03-30 14:11:21.934452+0300 0xed Default 0x0 0 0 kernel: Expect a `deadbeef` in the error messages below 2026-03-30 14:11:21.934456+0300 0xed Default 0x0 0 0 kernel: (AppleEmbeddedPCIE) apcie[0:centauri-control]::_dartErrorHandler() InvalidPTE caused by read from address 0x9800 by SID 2 (RID 2:0:1/useCount 1/device <private>) 2026-03-30 14:11:21.934469+0300 0xed Default 0x0 0 0 kernel: (AppleT8110DART) Ignored dart-apcie0 (0xfbfffe18820b0000): DART(DART) error: SID 2 PTE invalid exception on read of DVA 0x9800 (SEG 0 PTE 0x2) ERROR_SID_SUMMARY 0x00003000 TIME 0x11242d43fd TTE 0xffffffffffffffff AXI_ID 0 We do not have any correlation between machines, usage pattern or installed applications. Uninstalling the network protection features seem to largely fix the issues, even though we have heard of crashes happening even in safe mode or with our network extension disabled from system settings. We weren't able to reproduce internally and it seems to happen completely random on client machines, but often enough to be disrupting. Can you tell us please if this is a known problem and if there's a workaround or what can we do to narrow it down? Thanks.
36
2
4k
4d
Custom ethernet interface with userspace transport via DriverKit
We're developing a custom Thunderbolt device and want to expose it to macOS as an ethernet interface, while owning the full network stack implementation up to and including IP, TCP and UDP — bypassing the macOS network stack for those layers. Is IOEthernetController the right DriverKit approach for this, and does it allow intercepting traffic before it reaches the macOS IP stack?
3
0
113
6d
Getting a basic URL Filter to work
I haven’t been able to get this to work at any level! I’m running into multiple issues, any light shed on any of these would be nice: I can’t implement a bloom filter that produces the same output as can be found in the SimpleURLFilter sample project, after following the textual description of it that’s available in the documentation. No clue what my implementation is doing wrong, and because of the nature of hashing, there is no way to know. Specifically: The web is full of implementations of FNV-1a and MurmurHash3, and they all produce different hashes for the same input. Can we get the proper hashes for some sample strings, so we know which is the “correct” one? Similarly, different implementations use different encodings for the strings to hash. Which should we use here? The formulas for numberOfBits and numberOfHashes give Doubles and assign them to Ints. It seems we should do this conversing by rounding them, is this correct? Can we get a sample correct value for the combined hash, so we can verify our implementations against it? Or ignoring all of the above, can we have the actual code instead of a textual description of it? 😓 I managed to get Settings to register my first attempt at this extension in beta 1. Now, in beta 2, any other project (including the sample code) will redirect to Settings, show the Allow/Deny message box, I tap Allow, and then nothing happens. This must be a bug, right? Whenever I try to enable the only extension that Settings accepted (by setting its isEnabled to true), its status goes to .stopped and the error is, of course, .unknown. How do I debug this? While the extension is .stopped, ALL URL LOADS are blocked on the device. Is this to be expected? (shouldFailClosed is set to false) Is there any way to manually reload the bloom filter? My app ships blocklist updates with background push, so it would be wasteful to fetch the filter at a fixed interval. If so, can we opt out of the periodic fetch altogether? I initially believed the API to be near useless because I didn’t know of its “fuzzy matching” capabilities, which I’ve discovered by accident in a forum post. It’d be nice if those were documented somewhere! Thanks!!
85
2
8.4k
6d
Packet tunnel provider sleep mechanism
We are developing a network extension that utilises the NEPacketTunnelProvider. We have noticed when the extension is running, and the phone screen is off, after about 10 seconds the device goes to system sleep (as evidenced by messages like “suspended timer for imminent system sleep” in the console logs) and the network extension simply won’t run any code during this time, therefore stopping traffic flow. When the device wakes up from sleep, such as when the screen comes on the network extension resumes executing code and runs normally. The use case is relaying traffic from a device on the same Wi-Fi network to our server via the iPhone's cell socket. As such, we need it to work reliably when the screen is off and not freeze the network extension. Is there any way to prevent the device from sleeping and freezing our extension when the screen is off? Also, if sleep causes the extension to pause code execution, then how would system services like APNS or includeAllNetworks (which forces all traffic through the tunnel) even work?
2
0
160
6d
Network Extension behaviour with PAC
Hello, We have a Network extension transparent proxy (NETransparentProxyProvider) that receives browser TCP flows as NEAppProxyTCPFlow. For each flow we create an NWConnection to the flow's original destination and set NEParameters.preferNoProxies = true - expecting the outbound connection to bypass the user's HTTP/HTTPS proxy and PAC so it goes to the destination server directly. However, in practice we see connections still being redirected to local proxy after being evaluated against the PAC rules using the destination IP and port. Our questions are: Could we expect preferNoProxies to be respected when a PAC exist on the endpoint and supersede the PAC rule decision? If yes, what would be the best way to file a bug and what information do you need? If not, is there any other way of making sure that the outbound NWConnection created by the transparent proxy is not redirected to a proxy and goes directly to the destination? One other way of avoiding our NWConnection being redirected to the proxy is to use hostname instead of destination IP. Would there be a reliable way of getting hostname for the NEAppProxyTCPFlow so that PAC can correctly filter all NWConnection based on rules? We have explored remoteHostname but it's generally not available for connections from browsers other than Safari.
2
0
158
6d
includeAllNetworks and in-tunnel networking
There are cases where our VPN app would like to be able to send traffic inside the tunnel. It seems that when includeAllNetworks is set to true, there is no way to create a network socket (regardless of API, we've tried the unix socket API, Network framework by specifying the network interface and the deprecated Network Extension famework createTCPConnectionThroughTunnel) that works. Are there any plans to relieve us from having to ship a user space networking stack just to send some packets inside the tunnel from the packet tunnel process?
3
0
72
6d
Any update on FB13890736?
Given the details are undocumented "feature" of VPN/networking (but shared by an engineer in a 1:1 lab at WWDC24) I'm not including details here. That said, it seems surprising that VPNs can suddenly disconnect overnight with no warning. Can this bug fix be prioritized during the iOS 27 cycle?
2
0
113
6d
VPN: Internet inaccessible and include routes traffic is dropped
When enforceRoutes = YES is set on a split tunnel VPN configuration containing only excluded routes, all traffic matching the included routes is silently dropped — no packets reach the VPN tunnel. Only the excluded routes route correctly via the physical adapter. Setting enforceRoutes = NO with an identical configuration restores full connectivity immediately, confirming the issue is specific to the combination of enforceRoutes = YES and a non-empty excludedRoutes. This has been verified on iPadOS 26. Test Environment Device: iPad pro 4th gen OS Version: iPadOS 26.0 VPN Type: NEPacketTunnelProvider VPN Configuration (NEPacketTunnelNetworkSettings) tunnelRemoteAddress = 103.135.123.108 DNSSettings = { protocol = cleartext server = (10.34.250.51) } IPv4Settings = { configMethod = manual addresses = (10.34.247.235) subnetMasks = (255.255.255.255) includedRoutes = ( { destinationAddress = 0.0.0.0 destinationSubnetMask = 0.0.0.0 } ) excludedRoutes = ( { destinationAddress = 10.168.10.182 destinationSubnetMask = 255.255.255.255 } ) overridePrimary = NO } MTU = 1400 enforceRoutes = YES includeAllNetworks = NO Reproduction Steps Configure NEPacketTunnelProvider with the settings above Set protocolConfiguration.enforceRoutes = YES Set protocolConfiguration.includeAllNetworks = NO Establish VPN connection and wait for Connected status Attempt to access any internet resource Observed Behavior Excluded route (10.168.10.182) correctly routes via physical adapter — confirmed in Wireshark Included routes (0.0.0.0/0) — zero packets visible in Wireshark on any interface, traffic completely dropped Internet fully inaccessible — no DNS responses, no TCP connections established Setting enforceRoutes = NO with an identical route configuration and all other settings unchanged restores full internet connectivity immediately. No other change is made.
1
1
93
6d
Per app network extension filter
Recently, the number of cybersecurity attacks has been steadily increasing. For corporate users, access is provided through special extensions that allow traffic from a specific application to be routed through a tunnel. However, connecting a device to an MDM solution is convenient for large customers, but it creates challenges for small companies and developer teams that need to secure their network connections (for example, when a specific application must be isolated so that all of its traffic is routed exclusively through the tunnel), or protect their local infrastructure by preventing external applications from establishing network connections to unexpected servers (for instance, some applications may make requests to random servers in an attempt to determine their network environment).
2
3
96
6d
Network Extension Resources
General: Forums subtopic: App & System Services > Networking DevForums tag: Network Extension Network Extension framework documentation Routing your VPN network traffic article Filtering traffic by URL sample code Filtering Network Traffic sample code TN3120 Expected use cases for Network Extension packet tunnel providers technote TN3134 Network Extension provider deployment technote TN3165 Packet Filter is not API technote Network Extension and VPN Glossary forums post Debugging a Network Extension Provider forums post Exporting a Developer ID Network Extension forums post Network Extension Framework Entitlements forums post Network Extension vs ad hoc techniques on macOS forums post Network Extension Provider Packaging forums post NWEndpoint History and Advice forums post Extra-ordinary Networking forums post Wi-Fi management: Understanding NEHotspotConfigurationErrorInternal forums post See also Networking Resources for general networking resources, including information about Wi-Fi. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
Replies
0
Boosts
0
Views
3.3k
Activity
Mar ’26
Local Push - app-push-provider
Eons ago we were approved in the older entitlement method where we had to apply an Entitlement to our provisioning profile via a dropdown. We'd basically attach "Local Push Provider (Dist)" to our profile. That broke in May of 2025 when our fastlane process could no longer automate the creation of a provisioning profile with that profile attached. We learned the future was the capabilities so we submitted a request to migrate our Local Push Provider to a capability - https://developer.apple.com/contact/request/entitlement-migration-requests/ Meanwhile a new client wanted a white-labeled iteration of our app. So a new client requested the capability of Local Push via https://developer.apple.com/contact/request/local-push-connectivity and it worked in roughly 4 weeks. Their account now has "Network Extensions (additional values)" on the identifier which grants access to app-push-provider. Our build is fully automated - everything works. So we waited on our migration request and after months passed, we submitted in October of 2025 a new entitlement request for Local Push as our submit to migrate went stale. It never arrived again. So I started a case in 2026 roughly 6 months later - 102869206062. After many escalations I've been told: I wanted to provide an update to you regarding your entitlement request. It appears that your entitlement no longer requires a request. The channel you’ve reached is actually set up to provide administrative support to Apple Developers and those enrolled in the Apple Developer Program I just wanted to follow-up with you and ask you to please request the Network Extensions Entitlement again (19627183) It seems the overarching point is Network Extensions are no longer required for approval, but it seems app-push-provider (LocalPush) is. I don't want a random forum post to be a support thread. So looking for clarity on 2 points. Can you obtain app-push-provider (network extension) without Apple approval? Is this doc out of date? https://developer.apple.com/documentation/networkextension/local-push-connectivity To use the Local Push Connectivity API, your app must have the Network Extensions Entitlement with the app-push-provider value. Request this entitlement from the Entitlement Request Page. After you receive the entitlement, apply it to both your app target and your provider extension target. tldr; ➜ Desktop security cms -D -i match_ClientApp.mobileprovision| plutil -p - | grep 'push' 0 => "app-push-provider" ➜ Desktop security cms -D -i match_OurApp.mobileprovision| plutil -p - | grep 'push' ➜ Desktop
Replies
2
Boosts
0
Views
37
Activity
4m
NEURLFilter / SimpleURLFilter: neagent fails to open URL prefilter mmap file with errno 13 Permission denied
I am testing NEURLFilter on macOS using the SimpleURLFilter sample, and I am seeing a failure from neagent while it is saving the local URL prefilter Bloom filter to its mmap file. The relevant log is: neagent +[NEBloomFilter mmapToFile:data:dataLength:numberOfBits:numberOfHashes:murmurSeed:tag:]: NEBloomFilter - failed to open mmap file /private/var/db/urlPrefilter/com.apple.networkextension.url-prefilter-data.temp.com.example.apple-samplecode.SimpleURLFilterTC3Q7MAJXF <errno 13 - Permission denied> neagent <NEAgentURLFilterExtension: 0xc8ce64280>: -[NEAgentURLFilterExtension startURLFilter]_block_invoke - Failed to save first fetch of pre-filter data Environment: macOS: 26.5.1 (25F80) Xcode: 26.5 (17F42) Platform: macOS Signing type: Apple Development (automatically manage signing) What I am doing: Build and run the containing app. Save and enable the NEURLFilterManager configuration. The URL filter provider starts. The provider's prefilter code is reached. neagent logs the mmap failure above while trying to open a temporary file under /private/var/db/urlPrefilter. Expected result: neagent should be able to create or open its system-managed URL prefilter cache / mmap file under /private/var/db/urlPrefilter, and the local Bloom filter should be loaded successfully. Actual result: neagent fails to open the temporary mmap file with errno 13 Permission denied: /private/var/db/urlPrefilter/com.apple.networkextension.url-prefilter-data.temp.<bundle/team-specific suffix> I am not manually creating, modifying, or chmod/chown-ing /private/var/db/urlPrefilter or anything inside it. The directory and its contents are entirely system-managed. The failure appears to happen inside neagent while it is handling the system-managed URL prefilter cache. The failure occurs at the mmapToFile: step while neagent saves the Bloom filter prefilter data. Directory state: drwxr-xr-x 2 root wheel 64 /private/var/db/urlPrefilter Has anyone else encountered this? Any suggestions on what could cause neagent to fail with errno 13 on its own mmap file under /private/var/db/urlPrefilter?
Replies
0
Boosts
2
Views
24
Activity
1h
how to remove hotspot-provider
I previously attempted to apply for the hotspot-provider entitlement but was rejected. I no longer require this entitlement. I need to remove the hotspot-provider permission although the Network Extensions capability is checked. However, the generated provisioning profile still includes the hotspot-provider permission, which causes error 409 when I upload the IPA file. I only need the Network Extensions entitlement. Could you please advise how to remove hotspot-provider from the provisioning profile?
Replies
1
Boosts
0
Views
54
Activity
3h
Network Extension and DoH with preresolved IPs
Howdy, I've noticed a strange behavior recently on my macos (26.5.1) when using my System Extension-hosted Network Extension with a Packet Tunnel Provider inside: let dnsSettings = NEDNSOverHTTPSSettings(servers: ["8.8.8.8", "8.8.4.4"]) dnsSettings.serverURL = URL(string: "https://dns.google/dns-query") settings.dnsSettings = dnsSettings I have always expected this block to not need any DNS resolution, since IPs for dns.google are preconfigured, however not sure it's been the case lately. I see normal DNS requests to the addresses above to :53. Once resolved, no more DNS traffic, just :443 via TUN. Is it possible that some changes were introduced in the past months that would make macos to have to resolve dns.google with regular DNS before switching over to DoH?
Replies
0
Boosts
0
Views
6
Activity
3h
A Wi-Fi Aware network adapter has appeared in macOS 27 beta.
When entering the following command in macOS 27 beta: lvbojie@Mac ~ % netstat -I nan0 1 Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll nan0* 1500 <Link#25> 66:31:00:4c:3c:b5 0 0 41 0 0 nan0* 1500 fe80::6431: fe80:19::6431:ff: 0 - 41 - - liushicong@Mac ~ % netstat -I nan0 1 The nan0 network interface is displayed. Does this indicate that macOS will support Wi-Fi Aware in the near future?
Replies
1
Boosts
0
Views
75
Activity
4h
Requesting Network Extension Capability
One thing I wanted to confirm, suppose i submit one request to onboard OHTTP relay for one organisation app and it gets approved, so can I re submit the request with different bundle ID for other organisation and same PIR server, same OHTTP server ? Or do we need different domain name ?
Replies
8
Boosts
0
Views
446
Activity
1d
NEFilterDataProvider activation on consumer iOS — saveToPreferences fails (code 5), .mobileconfig requires MDM
Hello, I'm developing a gambling blocker app that uses NEFilterDataProvider. My app was approved on the App Store, but the core feature doesn't work for end users. I have the content-filter-provider entitlement. Issue 1 — saveToPreferences() fails in distribution builds In dev builds (Xcode direct install), NEFilterManager.saveToPreferences() works fine — iOS shows a permission dialog and the filter is registered. In distribution builds (TestFlight/App Store), it fails immediately: NEFilterErrorDomain code 5 — Operation not permitted Console log from nehelper: "Creating a content filter configuration is only allowed through profile in production version" Issue 2 — .mobileconfig profile requires MDM Following the Console hint, I tried a .mobileconfig profile with com.apple.webcontent-filter payload (ContentFilterUUID, FilterType: Plugin, PluginBundleID). On an unsupervised consumer iPhone (iOS 18.5), installation fails: Profile Installation Failed — MDM required Question: What is the correct mechanism to activate a NEFilterDataProvider on a consumer (non-MDM) iPhone in a distribution build? Is there a specific entitlement or approval process I'm missing? (DTS Case-ID: 20087732)
Replies
8
Boosts
0
Views
416
Activity
1d
URL Filters not activating on iOS 27 beta
(Also submitted as FB23072541) iOS 27 beta 1 brings a brand new error which ends up resulting in a state of .serverSetupIncomplete: <NEPIRChecker: 0x7de6c79b60>: -[NEPIRChecker start:responseQueue:completionHandler:]_block_invoke - PIR status returned error <Error Domain=com.apple.CipherML Code=1100 "Unable to query status due to errors: Error details were logged and redacted." UserInfo={NSLocalizedDescription=Unable to query status due to errors: Error details were logged and redacted., NSUnderlyingError=0x7de712f4e0 {Error Domain=com.apple.CipherML Code=1800 "Error details were logged and redacted." UserInfo={NSLocalizedDescription=Error details were logged and redacted.}}}> <NEAgentURLFilterExtension: 0x7de6d24e60>: -[NEAgentURLFilterExtension startURLFilter]_block_invoke - Failed to startFilter <Error Domain=NEMembershipCheckerErrorDomain Code=3 "(null)"> What’s a NEMembershipChecker? Member of what? Digging deeper I found these: Failed to prefetch tokens for group 'site.kaylees.Wipr2': Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good, NSErrorFailingURLKey=https://pirissuer.kaylees.site/token-key-for-user-token, NSUnderlyingError=0x7517125a40 {Error Domain=NSPOSIXErrorDomain Code=50 "Network is down" UserInfo={NSDescription=Network is down}}, _NSURLErrorPrivacyProxyFailureKey=true, NSLocalizedDescription=The Internet connection appears to be offline.} queryStatus(for:options:) threw an error: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, LQM: good, NSErrorFailingURLKey=https://pirissuer.kaylees.site/token-key-for-user-token, NSUnderlyingError=0x7517125b00 {Error Domain=NSPOSIXErrorDomain Code=50 "Network is down" UserInfo={NSDescription=Network is down}}, _NSURLErrorPrivacyProxyFailureKey=true, NSLocalizedDescription=The Internet connection appears to be offline.} The connection and the URL mentioned are fine of course, but "Network is down” now? This new problem only affects the App Store version of my app – not present if I install from Xcode. Users report that oddly, having an active VPN on the device works around this bug.
Replies
2
Boosts
2
Views
132
Activity
1d
NEAppProxyTCPFlow: How to distinguish half-close from full connection close
I'm implementing a NETransparentProxyProvider and trying to preserve the original TCP connection semantics as transparently as possible. The current API of NEAppProxyTCPFlow appears not to provide a way to distinguish between the following situations: The client has performed a half-close by calling shutdown(SHUT_WR) (i.e. closed only its write side). The client has fully closed the socket/connection. When readData(completionHandler:) returns empty data, indicating EOF, I cannot determine which of the two cases above has occurred. This creates a problem when forwarding the connection to the upstream server. Upon receiving empty data from the flow, should the corresponding server-side connection: Perform a half-close (close only the write side / send FIN)? Be fully closed? Currently, I always perform a half-close on the server-side connection. While this almost preserves the original flow semantics, it can lead to leaked connections, since the upstream connection may remain in FIN_WAIT_2 indefinitely. Is there any supported way to determine whether the originating connection was half-closed or fully closed? If not, what is the recommended approach for implementing a transparent TCP proxy that needs to accurately preserve TCP shutdown semantics? Any guidance would be appreciated.
Replies
2
Boosts
1
Views
102
Activity
2d
Kernel panics on M5 devices with network extension
Hello, We have a security solution which intercepts network traffic for inspection using a combination of Transparent Proxy Provider and Content filter. Lately we are seeing reports from the market that on M5 Macbooks and A18 Neos the system will kernel panic using our solution, even though it never happens on M1-M4 and no significant code changes were made in the mean time. All crashes seem to be related to an internal double free in the kernel: panic(cpu 0 caller 0xfffffe003bb68224): skmem_slab_free_locked: attempt to free invalid or already-freed obj 0xf2fffe29e15f2400 on skm 0xf6fffe2518aaa200 @skmem_slab.c:646 Debugger message: panic Memory ID: 0xff OS release type: User OS version: 25D2128 Kernel version: Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:38 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6050 Additionally, from further log inspection, before panics we find some weird kernel messages which seem to be related to some DMA operations gone wrong in the network driver on some machines: 2026-03-30 14:11:21.779124+0300 0x30f2 Default 0x0 873 0 Arc: (Network) [com.apple.network:connection] [C9.1.1.1 IPv4#e5b4bb04:443 in_progress socket-flow (satisfied (Path is satisfied), interface: en0[802.11], ipv4, ipv6, dns, uses wifi, flow divert agg: 1, LQM: good)] event: flow:start_connect @0.075s 2026-03-30 14:11:21.780015+0300 0x1894 Default 0x0 0 0 kernel: (402262746): No more valid control units, disabling flow divert 2026-03-30 14:11:21.780017+0300 0x1894 Default 0x0 0 0 kernel: (402262746): Skipped all flow divert services, disabling flow divert 2026-03-30 14:11:21.780102+0300 0x1894 Default 0x0 0 0 kernel: SK[2]: flow_entry_alloc fe "0 proc kernel_task(0)Arc nx_port 1 flow_uuid D46E230E-B826-4E0A-8C59-4C4C8BF6AA60 flags 0x14120<CONNECTED,QOS_MARKING,EXT_PORT,EXT_FLOWID> ipver=4,src=<IPv4-redacted>.49703,dst=<IPv4-redacted>.443,proto=0x06 mask=0x0000003f,hash=0x04e0a750 tp_proto=0x06" 2026-03-30 14:11:21.780194+0300 0x1894 Default 0x0 0 0 kernel: tcp connect outgoing: [<IPv4-redacted>:49703<-><IPv4-redacted>:443] interface: en0 (skipped: 0) so_gencnt: 14634 t_state: SYN_SENT process: Arc:873 SYN in/out: 0/1 bytes in/out: 0/0 pkts in/out: 0/0 rtt: 0.0 ms rttvar: 250.0 ms base_rtt: 0 ms error: 0 so_error: 0 svc/tc: 0 flow: 0x9878386f 2026-03-30 14:11:21.934431+0300 0xed Default 0x0 0 0 kernel: Hit error condition (not panicking as we're in error handler): t8110dart <private> (dart-apcie0): invalid SID 2 TTBR access: level 1 table_index 0 page_offset 0x2 2026-03-30 14:11:21.934432+0300 0xed Default 0x0 0 0 kernel: [ 73.511690]: arm_cpu_init(): cpu 6 online 2026-03-30 14:11:21.934441+0300 0xed Default 0x0 0 0 kernel: [ 73.511696]: arm_cpu_init(): cpu 9 online 2026-03-30 14:11:21.934441+0300 0xed Default 0x0 0 0 kernel: [ 73.569033]: arm_cpu_init(): cpu 6 online 2026-03-30 14:11:21.934441+0300 0xed Default 0x0 0 0 kernel: [ 73.569038]: arm_cpu_init(): cpu 9 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.577453]: arm_cpu_init(): cpu 7 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.586328]: arm_cpu_init(): cpu 5 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.586332]: arm_cpu_init(): cpu 8 online 2026-03-30 14:11:21.934442+0300 0xed Default 0x0 0 0 kernel: [ 73.621392]: (dart-apcie0) AppleT8110DART::_fatalException: dart-apcie0 (<ptr>): DART DART SID exception ERROR_SID_SUMMARY 0x00003000 ERROR_ADDRESS 0x0000000000009800 2026-03-30 14:11:21.934443+0300 0xed Default 0x0 0 0 kernel: [ 73.621397]: Hit error condition (not panicking as we're in error handler): 2026-03-30 14:11:21.934443+0300 0xed Default 0x0 0 0 kernel: t8110dart <ptr> (dart-apcie0): invalid SID 2 TTBR access: level 1 table_index 0 page_offset 0x2Expect a `deadbeef` in the error messages below 2026-03-30 14:11:21.934452+0300 0xed Default 0x0 0 0 kernel: Expect a `deadbeef` in the error messages below 2026-03-30 14:11:21.934456+0300 0xed Default 0x0 0 0 kernel: (AppleEmbeddedPCIE) apcie[0:centauri-control]::_dartErrorHandler() InvalidPTE caused by read from address 0x9800 by SID 2 (RID 2:0:1/useCount 1/device <private>) 2026-03-30 14:11:21.934469+0300 0xed Default 0x0 0 0 kernel: (AppleT8110DART) Ignored dart-apcie0 (0xfbfffe18820b0000): DART(DART) error: SID 2 PTE invalid exception on read of DVA 0x9800 (SEG 0 PTE 0x2) ERROR_SID_SUMMARY 0x00003000 TIME 0x11242d43fd TTE 0xffffffffffffffff AXI_ID 0 We do not have any correlation between machines, usage pattern or installed applications. Uninstalling the network protection features seem to largely fix the issues, even though we have heard of crashes happening even in safe mode or with our network extension disabled from system settings. We weren't able to reproduce internally and it seems to happen completely random on client machines, but often enough to be disrupting. Can you tell us please if this is a known problem and if there's a workaround or what can we do to narrow it down? Thanks.
Replies
36
Boosts
2
Views
4k
Activity
4d
Custom ethernet interface with userspace transport via DriverKit
We're developing a custom Thunderbolt device and want to expose it to macOS as an ethernet interface, while owning the full network stack implementation up to and including IP, TCP and UDP — bypassing the macOS network stack for those layers. Is IOEthernetController the right DriverKit approach for this, and does it allow intercepting traffic before it reaches the macOS IP stack?
Replies
3
Boosts
0
Views
113
Activity
6d
Getting a basic URL Filter to work
I haven’t been able to get this to work at any level! I’m running into multiple issues, any light shed on any of these would be nice: I can’t implement a bloom filter that produces the same output as can be found in the SimpleURLFilter sample project, after following the textual description of it that’s available in the documentation. No clue what my implementation is doing wrong, and because of the nature of hashing, there is no way to know. Specifically: The web is full of implementations of FNV-1a and MurmurHash3, and they all produce different hashes for the same input. Can we get the proper hashes for some sample strings, so we know which is the “correct” one? Similarly, different implementations use different encodings for the strings to hash. Which should we use here? The formulas for numberOfBits and numberOfHashes give Doubles and assign them to Ints. It seems we should do this conversing by rounding them, is this correct? Can we get a sample correct value for the combined hash, so we can verify our implementations against it? Or ignoring all of the above, can we have the actual code instead of a textual description of it? 😓 I managed to get Settings to register my first attempt at this extension in beta 1. Now, in beta 2, any other project (including the sample code) will redirect to Settings, show the Allow/Deny message box, I tap Allow, and then nothing happens. This must be a bug, right? Whenever I try to enable the only extension that Settings accepted (by setting its isEnabled to true), its status goes to .stopped and the error is, of course, .unknown. How do I debug this? While the extension is .stopped, ALL URL LOADS are blocked on the device. Is this to be expected? (shouldFailClosed is set to false) Is there any way to manually reload the bloom filter? My app ships blocklist updates with background push, so it would be wasteful to fetch the filter at a fixed interval. If so, can we opt out of the periodic fetch altogether? I initially believed the API to be near useless because I didn’t know of its “fuzzy matching” capabilities, which I’ve discovered by accident in a forum post. It’d be nice if those were documented somewhere! Thanks!!
Replies
85
Boosts
2
Views
8.4k
Activity
6d
Packet tunnel provider sleep mechanism
We are developing a network extension that utilises the NEPacketTunnelProvider. We have noticed when the extension is running, and the phone screen is off, after about 10 seconds the device goes to system sleep (as evidenced by messages like “suspended timer for imminent system sleep” in the console logs) and the network extension simply won’t run any code during this time, therefore stopping traffic flow. When the device wakes up from sleep, such as when the screen comes on the network extension resumes executing code and runs normally. The use case is relaying traffic from a device on the same Wi-Fi network to our server via the iPhone's cell socket. As such, we need it to work reliably when the screen is off and not freeze the network extension. Is there any way to prevent the device from sleeping and freezing our extension when the screen is off? Also, if sleep causes the extension to pause code execution, then how would system services like APNS or includeAllNetworks (which forces all traffic through the tunnel) even work?
Replies
2
Boosts
0
Views
160
Activity
6d
Network Extension behaviour with PAC
Hello, We have a Network extension transparent proxy (NETransparentProxyProvider) that receives browser TCP flows as NEAppProxyTCPFlow. For each flow we create an NWConnection to the flow's original destination and set NEParameters.preferNoProxies = true - expecting the outbound connection to bypass the user's HTTP/HTTPS proxy and PAC so it goes to the destination server directly. However, in practice we see connections still being redirected to local proxy after being evaluated against the PAC rules using the destination IP and port. Our questions are: Could we expect preferNoProxies to be respected when a PAC exist on the endpoint and supersede the PAC rule decision? If yes, what would be the best way to file a bug and what information do you need? If not, is there any other way of making sure that the outbound NWConnection created by the transparent proxy is not redirected to a proxy and goes directly to the destination? One other way of avoiding our NWConnection being redirected to the proxy is to use hostname instead of destination IP. Would there be a reliable way of getting hostname for the NEAppProxyTCPFlow so that PAC can correctly filter all NWConnection based on rules? We have explored remoteHostname but it's generally not available for connections from browsers other than Safari.
Replies
2
Boosts
0
Views
158
Activity
6d
includeAllNetworks and in-tunnel networking
There are cases where our VPN app would like to be able to send traffic inside the tunnel. It seems that when includeAllNetworks is set to true, there is no way to create a network socket (regardless of API, we've tried the unix socket API, Network framework by specifying the network interface and the deprecated Network Extension famework createTCPConnectionThroughTunnel) that works. Are there any plans to relieve us from having to ship a user space networking stack just to send some packets inside the tunnel from the packet tunnel process?
Replies
3
Boosts
0
Views
72
Activity
6d
Any update on FB13890736?
Given the details are undocumented "feature" of VPN/networking (but shared by an engineer in a 1:1 lab at WWDC24) I'm not including details here. That said, it seems surprising that VPNs can suddenly disconnect overnight with no warning. Can this bug fix be prioritized during the iOS 27 cycle?
Replies
2
Boosts
0
Views
113
Activity
6d
What is included in `excludeDeviceCommunications`?
Thanks for being here! What is the behavior of this flag? The documentation is scant, to say the least.
Replies
3
Boosts
0
Views
118
Activity
6d
VPN: Internet inaccessible and include routes traffic is dropped
When enforceRoutes = YES is set on a split tunnel VPN configuration containing only excluded routes, all traffic matching the included routes is silently dropped — no packets reach the VPN tunnel. Only the excluded routes route correctly via the physical adapter. Setting enforceRoutes = NO with an identical configuration restores full connectivity immediately, confirming the issue is specific to the combination of enforceRoutes = YES and a non-empty excludedRoutes. This has been verified on iPadOS 26. Test Environment Device: iPad pro 4th gen OS Version: iPadOS 26.0 VPN Type: NEPacketTunnelProvider VPN Configuration (NEPacketTunnelNetworkSettings) tunnelRemoteAddress = 103.135.123.108 DNSSettings = { protocol = cleartext server = (10.34.250.51) } IPv4Settings = { configMethod = manual addresses = (10.34.247.235) subnetMasks = (255.255.255.255) includedRoutes = ( { destinationAddress = 0.0.0.0 destinationSubnetMask = 0.0.0.0 } ) excludedRoutes = ( { destinationAddress = 10.168.10.182 destinationSubnetMask = 255.255.255.255 } ) overridePrimary = NO } MTU = 1400 enforceRoutes = YES includeAllNetworks = NO Reproduction Steps Configure NEPacketTunnelProvider with the settings above Set protocolConfiguration.enforceRoutes = YES Set protocolConfiguration.includeAllNetworks = NO Establish VPN connection and wait for Connected status Attempt to access any internet resource Observed Behavior Excluded route (10.168.10.182) correctly routes via physical adapter — confirmed in Wireshark Included routes (0.0.0.0/0) — zero packets visible in Wireshark on any interface, traffic completely dropped Internet fully inaccessible — no DNS responses, no TCP connections established Setting enforceRoutes = NO with an identical route configuration and all other settings unchanged restores full internet connectivity immediately. No other change is made.
Replies
1
Boosts
1
Views
93
Activity
6d
Per app network extension filter
Recently, the number of cybersecurity attacks has been steadily increasing. For corporate users, access is provided through special extensions that allow traffic from a specific application to be routed through a tunnel. However, connecting a device to an MDM solution is convenient for large customers, but it creates challenges for small companies and developer teams that need to secure their network connections (for example, when a specific application must be isolated so that all of its traffic is routed exclusively through the tunnel), or protect their local infrastructure by preventing external applications from establishing network connections to unexpected servers (for instance, some applications may make requests to random servers in an attempt to determine their network environment).
Replies
2
Boosts
3
Views
96
Activity
6d