I'm developing a macOS app using a Network Extension Packet Tunnel Provider. The System Extension activates successfully, but NETunnelProviderManager.saveToPreferences() consistently fails with permission denied.
Environment
- macOS virtual machine running under UTM
- Host app and embedded Packet Tunnel System Extension signed with Developer ID
- App notarization verified successfully
- System Extension status:
[activated enabled] - Packet Tunnel has
com.apple.security.app-sandbox=trueandcom.apple.security.network.client=true - Host app has the Network Extension entitlement
Reproduction
- Launch the installed, notarized HostApp.
- Call
NETunnelProviderManager.loadAllFromPreferences(). - No manager matching the Packet Tunnel provider bundle identifier is found.
- Create a
NETunnelProviderManager. - Configure
NETunnelProviderProtocolwith the Packet Tunnel provider bundle identifier and a server address. - Set
localizedDescriptionandisEnabled = true. - Call
saveToPreferences().
Observed result
On October 30, 2026, the following events were recorded:
11:25:32.643 PROTOTYPE_MANAGER_CREATED
11:25:32.643 PREFERENCES_LOADED
11:25:32.643 PROTOTYPE_VPN_AUTH_SKIPPED
11:25:32.646 Saving configuration ... with existing signature (null)
11:25:33.766 NEConfigurationErrorDomain Code=10 "permission denied"
11:25:33.766 NEVPNErrorDomain Code=5 "permission denied"
The app never reaches startVPNTunnel().
What I've already checked
- Developer ID code signing verification succeeds.
- Notarization and stapler validation succeed.
- The System Extension is activated and enabled.
- The failure reproduces both with and without
created.loadFromPreferences()before saving. - An explicit VPN authorization step is disabled in these reproduction runs.
Questions
- What conditions can cause
NEConfigurationErrorDomain Code=10when a newly createdNETunnelProviderManageris saved? - Are there additional signing, entitlement, authorization, or configuration requirements for a Developer ID-distributed macOS Packet Tunnel app?
- Which NetworkExtension or
nehelperdiagnostics would help identify the specific permission check that fails? - Is there any known difference in this behavior when running under macOS virtualization?
I can provide a minimal reproduction project, sanitized logs, entitlement output, and a sysdiagnose privately if necessary.
Thank you for your guidance.