Hi,
I’m implementing a macOS DNS Proxy as a system extension and running into a persistent activation error:
OSSystemExtensionErrorDomain error 9 (validationFailed)
with the message:
extension category returned error
This happens both on an MDM‑managed Mac and on a completely clean Mac (no MDM, fresh install).
Setup
macOS: 15.x (clean machine, no MDM)
Xcode: 16.x
Team ID: AAAAAAA111 (test)
Host app bundle ID: com.example.agent.NetShieldProxy
DNS Proxy system extension bundle ID: com.example.agent.NetShieldProxy.dnsProxy
The DNS Proxy is implemented as a NetworkExtension system extension, not an app extension.
Host app entitlements
From codesign -d --entitlements :- /Applications/NetShieldProxy.app:
xml
com.apple.application-identifier
AAAAAAA111.com.example.agent.NetShieldProxy
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>AAAAAAA111</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.example.NetShieldmac</string>
</array>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
xml
com.apple.application-identifier
AAAAAAA111.com.example.agent.NetShieldProxy.dnsProxy
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>dns-proxy-systemextension</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>AAAAAAA111</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.example.NetShieldmac</string>
<string>group.example.NetShieldmac</string>
<string>group.example.agent.enterprise.macos</string>
<string>group.example.com.NetShieldmac</string>
</array>
DNS Proxy system extension Info.plist
On the clean Mac, from:
bash
plutil -p "/Applications/NetShieldProxy.app/Contents/Library/SystemExtensions/com.example.agent.NetShieldProxy.dnsProxy.systemextension/Contents/Info.plist"
I get:
json
{
"CFBundleExecutable" => "com.example.agent.NetShieldProxy.dnsProxy",
"CFBundleIdentifier" => "com.example.agent.NetShieldProxy.dnsProxy",
"CFBundleName" => "com.example.agent.NetShieldProxy.dnsProxy",
"CFBundlePackageType" => "SYSX",
"CFBundleShortVersionString" => "1.0.1.8",
"CFBundleSupportedPlatforms" => [ "MacOSX" ],
"CFBundleVersion" => "0.1.1",
"LSMinimumSystemVersion" => "13.5",
"NSExtension" => {
"NSExtensionPointIdentifier" => "com.apple.dns-proxy",
"NSExtensionPrincipalClass" => "com_example_agent_NetShieldProxy_dnsProxy.DNSProxyProvider"
},
"NSSystemExtensionUsageDescription" => "SYSTEM_EXTENSION_USAGE_DESCRIPTION"
}
The DNSProxyProvider class inherits from NEDNSProxyProvider and is built in the system extension target.
Activation code
In the host app, I use:
swift
import SystemExtensions
final class SystemExtensionActivator: NSObject, OSSystemExtensionRequestDelegate {
private let extensionIdentifier = "com.example.agent.NetShieldProxy.dnsProxy"
func activate(completion: @escaping (Bool) -> Void) {
let request = OSSystemExtensionRequest.activationRequest(
forExtensionWithIdentifier: extensionIdentifier,
queue: .main
)
request.delegate = self
OSSystemExtensionManager.shared.submitRequest(request)
}
func request(_ request: OSSystemExtensionRequest,
didFailWithError error: Error) {
let nsError = error as NSError
print("Activation failed:", nsError)
}
func request(_ request: OSSystemExtensionRequest,
didFinishWithResult result: OSSystemExtensionRequest.Result) {
print("Result:", result.rawValue)
}
}
Runtime behavior on a clean Mac (no MDM)
config.plist is created under /Library/Application Support/NetShield (via a root shell script).
A daemon runs, contacts our backend, and writes /Library/Application Support/NetShield/state.plist with a valid dnsToken and other fields.
The app NetShieldProxy.app is installed via a notarized, stapled Developer ID .pkg.
The extension bundle is present at:
/Applications/NetShieldProxy.app/Contents/Library/SystemExtensions/com.example.agent.NetShieldProxy.dnsProxy.systemextension.
When I press Activate DNS Proxy in the UI, I see in the unified log:
text
NetShieldProxy: [com.example.agent:SystemExtensionActivator] Requesting activation for system extension: com.example.agent.NetShieldProxy.dnsProxy
NetShieldProxy: [com.example.agent:SystemExtensionActivator] SystemExtensionActivator - activation failed: extension category returned error (domain=OSSystemExtensionErrorDomain code=9)
NetShieldProxy: [com.example.agent:SystemExtensionActivator] SystemExtensionActivator - OSSystemExtensionError code enum: 9
NetShieldProxy: [com.example.agent:SystemExtensionActivator] SystemExtensionActivator - validationFailed
And:
bash
systemextensionsctl list
-> 0 extension(s)
There is no prompt in Privacy & Security on this clean Mac.
Question
Given:
The extension is packaged as a system extension (CFBundlePackageType = SYSX) with NSExtensionPointIdentifier = "com.apple.dns-proxy".
Host and extension share the same Team ID and Developer ID Application cert.
Entitlements on the target machine match the provisioning profile and Apple’s docs for DNS Proxy system extensions (dns-proxy-systemextension).
This is happening on a clean Mac with no MDM profiles at all.
What are the likely reasons for OSSystemExtensionErrorDomain error 9 (validationFailed) with "extension category returned error" in this DNS Proxy system extension scenario?
Is there any additional configuration required for DNS Proxy system extensions (beyond entitlements and Info.plist) that could trigger this category-level validation failure?
Any guidance or examples of a working DNS Proxy system extension configuration (host entitlements + extension Info.plist + entitlements) would be greatly appreciated.
Thanks!
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I’m building a macOS app with a DNS Proxy system extension for Developer ID + notarization, deployed via MDM, and Xcode fails the Developer ID Release build with a provisioning profile mismatch for com.apple.developer.networking.networkextension.
Environment
macOS: Sequoia (15.7.2)
Xcode: 26.2
Distribution: Developer ID + notarization, deployed via MDM
Host bundle ID: com.mydns.agent.MyDNSMacProxy
DNS Proxy system extension bundle ID: com.mydns.agent.MyDNSMacProxy.dnsProxy
Host entitlements (Release):
File: MyDNSMacProxy/MyDNSMacProxyRelease.entitlements:
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>B234657989.com.mydns.agent.MyDNSMacProxy</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>dns-proxy</string>
</array>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>B234657989</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.mydns.MyDNSmac</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>B234657989.*</string>
</array>
</dict>
</plist>
xcodebuild -showBuildSettings -scheme MyDNSMacProxy -configuration Release :
PROVISIONING_PROFILE_SPECIFIER = main MyDNSMacProxy5
CODE_SIGN_IDENTITY = Developer ID Application
Host Developer ID profile
main_MyDNSMacProxy5.provisionprofile (via security cms -D):
"Entitlements" => {
"com.apple.application-identifier" => "B234657989.com.mydns.agent.MyDNSMacProxy"
"com.apple.developer.team-identifier" => "B234657989"
"com.apple.security.application-groups" => [ "group.com.mydns.MyDNSmac", ..., "B234657989.*" ]
"keychain-access-groups" => [ "B234657989.*" ]
"com.apple.developer.system-extension.install" => 1
"com.apple.developer.networking.networkextension" => [
"packet-tunnel-provider-systemextension",
"app-proxy-provider-systemextension",
"content-filter-provider-systemextension",
"dns-proxy-systemextension",
"dns-settings",
"relay",
"url-filter-provider",
"hotspot-provider"
]
}
So:
App ID, team ID, keychain and system‑extension.install match.
The profile’s com.apple.developer.networking.networkextension is a superset of what I request in the host entitlements (dns-proxy only).
System extension (for context)
DNS Proxy system extension target:
NSExtensionPointIdentifier = com.apple.dns-proxy
NetworkExtension → NEProviderClasses → com.apple.networkextension.dns-proxy → my provider class
Entitlements: com.apple.developer.networking.networkextension = ["dns-proxy-systemextension"]
This target uses a separate Developer ID profile and builds successfully.
Xcode error
Release build of the host fails with:
…MyDNSMacProxy.xcodeproj: error: Provisioning profile "main MyDNSMacProxy5" doesn't match the entitlements file's value for the com.apple.developer.networking.networkextension entitlement. (in target 'MyDNSMacProxy' from project 'MyDNSMacProxy')
Xcode UI also says:
Entitlements: 6 Included, 1 Missing Includes com.apple.developer.team-identifier, com.apple.application-identifier, keychain-access-groups, com.apple.developer.system-extension.install, and com.apple.security.application-groups. Doesn’t match entitlements file value for com.apple.developer.networking.networkextension.
Because of this, the app bundle isn’t produced and I can’t inspect the final signed entitlements.
Questions:
For com.apple.developer.networking.networkextension, should Xcode accept a subset of values in the entitlements (here just dns-proxy) as long as that value is allowed by the Developer ID profile, or does it currently require a stricter match?
Is the following configuration valid for Developer ID + MDM with a DNS Proxy system extension:
Host entitlements: ["dns-proxy"]
System extension entitlements: ["dns-proxy-systemextension"]
Host profile’s NE array includes the DNS Proxy system extension types.
If this is a known limitation or bug in how Xcode validates NE entitlements for Developer ID, is there a recommended workaround?
Thanks for any guidance.
Topic:
App & System Services
SubTopic:
Networking
Tags:
Network Extension
System Extensions
Code Signing
Developer ID