Failed to find a com.apple.networkextension.filter-data extension inside of app

Hi there. I've been working for quite a while prototyping a Content Filter app. I started with the SimpleFirewall code as a base, slowly making changes to it, as my use case is fairly different from the sample code - an internet safety app for kids, not a firewall.

I've spent a long time figuring out some of the intricacies of filtering NEFilterFlow objects, and working out the (fairly difficult) IPC communication between the system extension and the containing app. I have the app in a state now where it is not ready for distribution in the app store, but is ready for validation on a select number of internal test machines.

And here I must confess my almost total ignorance of many of the complexities in this realm. I've never built a macOS app before, and I only have one iOS app in the app store, and that was a much simpler use case (built with React Native, no tricky system extension stuff, and I leveraged TestFlight for testing with that app). So, I fully believe I might be making some total noob mistake here. I can say I've poured over these forums for hours trying lots of things, and I'm really stumped, and would greatly appreciate some detailed help here. 🙏

The problem


Anyway, the problem I'm having is that when I try to get the app to run on another Mac, I can't successfully get the system extension to install. I'll describe the error (as best I can understand it) directly below, and then further down give more information as to how I'm preparing the test application, since the problem might lie there.

When I try to activate the system extension from the containing app on a test machine, the activation requests succeeds far enough to prompt me to grant permission to install the extension, and when granted, it pops up the purple "(Redacted) would like to filter internet content". When I click "allow", however, the system extension shows up orange in the Network pref pane, labeled "not running." Pouring over the console logs, these two seem to be the most likely to shed light:

Code Block
(neagent) Failed to find a com.apple.networkextension.filter-data extension inside of app com.acmecorp.product


and:

Code Block
(nesessionmanager) com.acmecorp.product[3656]: Tearing down XPC connection due to setup error: Error Domain=NEAgentErrorDomain Code=2 "(null)"


I've inspected the contents of the app, and the system extension is properly packaged with the app. I built the SimpleFirewall app and compared the packaged app directory, and the file structure seems basically identical -- the system extension executable definitely is there. I put in a bunch of os_logs during the filter activation lifecycle process, logging out the bundle main url of the system extension, and it all seems correct, and seems to be pointing to files on the filesystem that exist. Also, I do get this encouraging log during the failing activation process:

Code Block
(sysext) Realizing target path: file:///Applications/MyApp.app/Contents/Library/SystemExtensions/com.acmecorp.product.systemextension/


Which has the correct file url, and seems to be indicating that the path to the extension was indeed found. But the extension just stays stuck orange, dead, no IPC communication succeeds, and I have to manually remove it from the Network prefs pane.

I've never had the problem building and running locally on the development machine from the derived data dir from Xcode.

How I'm testing


Since the problem might lie here, I'll describe how I'm getting the app over to the target test machine (which is a physical device, not a VM). Nothing super fancy -- I basically am just going to "Product" > "Archive" from within Xcode and creating an .xcarchive file. I then "show package contents", zip up the app file, and send it to the target machine, where I install it in the /Applications dir.

I did spend a long time figuring out how to add the UUID of the target machine to the provisioning profile before I could even get the container app to load. But I got that figured out and (as described above) the container app loads perfectly, it's only the system extension activation request that fails.

So... Can anyone lend me a hand? Am I going about trying to test correctly? Should I be creating the test app package some other way? Or is my (admittedly crude) method OK, and is it likely the problem lies in how I'm archiving or how the build is setup? Can anyone shed any light on the error?

Am I wrong in thinking that if it builds and runs correctly from Xcode on the dev machine, and I drag the app bundle over to another machine, it should run there too, assuming the test machine is in the provisioning profile, which it is? (Both machines are running Catalina, btw).

Thanks in advance!
Answered by Systems Engineer in 664772022
I want to address your problem first from a generalized standpoint:

I did a quick test of your workflow locally; archiving and exporting a development copy of a local content filter I maintain with a Network System Extension. From there I copied this development signed app to another local development machine. In this case I built on 10.15 and copied to a 11.0 machine for testing. On my 11.0 machine I moved the development app into /Application directory, logged the subsystems running in the container app and in the Network System Extension and was able to see everything running as usual. Now, this only works because like you mentioned, both machines are contained in the provisioning profile that was used to sign the development copy of the app and the Network System Extension. This is roughly equivalent to two members of your development team working together to develop and test locally.

Typically you would test this workflow with a distribution signed copy of your app. For this, you will need to create a Developer ID certificate and signing identity. From there you will need to change your content-filter-provider key to content-filter-provider-systemextension (see more here) and then Developer ID sign and Notarize your app to be distributed for testing.


Having said that above, the logs that you have provided do indicate that there is something wrong in your configuration and possibly the loading of the Network System Extension:

(neagent) Failed to find a com.apple.networkextension.filter-data extension inside of
app com.acmecorp.product

Code Block
(nesessionmanager) com.acmecorp.product[3656]: Tearing down XPC connection due to setup
error: Error Domain=NEAgentErrorDomain Code=2 "(null)"

I would concentrate on this side of communication between apps. If you need to, try removing the IPC connection between apps and see if your are able to at least initiate your Network System Extension, and that way you know where to focus your debugging.

If you find that you are unable to come to a resolution here, open a TSI and either myself or Quinn will take a closer look.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Accepted Answer
I want to address your problem first from a generalized standpoint:

I did a quick test of your workflow locally; archiving and exporting a development copy of a local content filter I maintain with a Network System Extension. From there I copied this development signed app to another local development machine. In this case I built on 10.15 and copied to a 11.0 machine for testing. On my 11.0 machine I moved the development app into /Application directory, logged the subsystems running in the container app and in the Network System Extension and was able to see everything running as usual. Now, this only works because like you mentioned, both machines are contained in the provisioning profile that was used to sign the development copy of the app and the Network System Extension. This is roughly equivalent to two members of your development team working together to develop and test locally.

Typically you would test this workflow with a distribution signed copy of your app. For this, you will need to create a Developer ID certificate and signing identity. From there you will need to change your content-filter-provider key to content-filter-provider-systemextension (see more here) and then Developer ID sign and Notarize your app to be distributed for testing.


Having said that above, the logs that you have provided do indicate that there is something wrong in your configuration and possibly the loading of the Network System Extension:

(neagent) Failed to find a com.apple.networkextension.filter-data extension inside of
app com.acmecorp.product

Code Block
(nesessionmanager) com.acmecorp.product[3656]: Tearing down XPC connection due to setup
error: Error Domain=NEAgentErrorDomain Code=2 "(null)"

I would concentrate on this side of communication between apps. If you need to, try removing the IPC connection between apps and see if your are able to at least initiate your Network System Extension, and that way you know where to focus your debugging.

If you find that you are unable to come to a resolution here, open a TSI and either myself or Quinn will take a closer look.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Matt, thanks for your reply. I'm going to carefully look at the link you provided and explore testing it in the alternate way you mention.

That said, I was just doing some more testing this morning, and I wanted to add one useful (I think) piece of info, that I wonder if you'd be willing to look into.

To rule out any mistakes on my part, this morning I downloaded a fresh copy of the FilteringNetworkContent sample code ("SimpleFirewall" app). I opened it up on Xcode, and the only change I made was to connect it to my appstoreconnect account with a provisioning profile including my secondary test target machine. Then I made an archive directly from the untouched example code, moved the app file over to the test machine.

When I did this, I got the exact same error:

Code Block
Failed to find a com.apple.networkextension.filter-data extension inside of app com.example.apple-samplecode.SimpleFirewall.MYTEAMID


So here's what I'm wondering. Would you be so kind as to try the same thing? I understand you have a network extension you use for testing, but I'm wondering if you'd be able to try a pristine copy of the SimpleFirewall app and see if you can install it on a different machine after building from Xcode. It seems like if the sample app won't run properly when built without modifications, maybe there's a fix or some additional information that could be useful to a lot of people trying to work with this type of app.
Also, I'm not sure if this is relevant or not, but when I created the archive (both with my app, and with the pristine SimpleFirewall test), I went through the process of "Validate App" from the Organizer screen. That required me to go to my App store connect account and create a dummy app for the validation process to succeed. I mention this just in case somehow my having done that caused this problem. All of these steps and options are pretty overwhelming and confusing for me, I admit.
If you want to dig into this further, I would open a TSI like I mentioned. One thing that may be relevant here is that I always reference my Network System Extension using the filterDataProviderBundleIdentifier property. For example:

Code Block swift
if filterManager.providerConfiguration == nil {
let providerConfiguration = NEFilterProviderConfiguration()
providerConfiguration.filterSockets = true
providerConfiguration.filterPackets = false
providerConfiguration.filterDataProviderBundleIdentifier = "com.example.containerapp.systemextensionbundleid"
filterManager.providerConfiguration = providerConfiguration
if let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String {
filterManager.localizedDescription = appName
}
}
filterManager.isEnabled = true
filterManager.saveToPreferences { saveError in ... }

And actually, I do this for all of the other Network System Extensions as well. Try this on your end to see if it produces favorable results as this is a delta between my sample code and the SimpleFirewall example.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Ok, took me a long time to figure out all of the signing, provisioning, entitlements, and notarization stuff, but when I finally successfully signed it with a developer ID and notarized it, it started working on the test machine. So maybe the error messages were misleading me and the true issue might have been less about the extension being built properly within the bundle, and more about permissions and entitlements.

Appreciate the help very much, thanks for your time.

Ok, took me a long time to figure out all of the signing, provisioning, entitlements, and notarization stuff, but when I finally successfully signed it with a developer ID and notarized it, it started working on the test machine.

Excellent news!

Appreciate the help very much, thanks for your time.

No problem. Always glad to help.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
I did want to update this thread that the distribution information for Content Filter Providers has now been updated.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hello there.

Ok, took me a long time to figure out all of the signing, provisioning, entitlements, and notarization stuff, but when I finally successfully signed it with a developer ID and notarized it, it started working on the test machine. So maybe the error messages were misleading me and the true issue might have been less about the extension being built properly within the bundle, and more about permissions and entitlements.

We are facing the same problem right now. Could you please give more details about what you changed regarding the signing, provisioning profiles, entitlements and notarization to make it work? We have revised the process and tested different alternatives unsuccessfully.

Thanks a lot in advance

Failed to find a com.apple.networkextension.filter-data extension inside of app
 
 
Q