Why does a sandboxed Flutter macOS app fail network calls with Operation not permitted, and which entitlement files must you edit?
answer
- App Sandbox is on by default
- two entitlement files per configuration
- network.client for outgoing requests
- network.server only in DebugProfile
- Xcode capabilities UI edits one file
basics
~10 sFlutter macOS apps are sandboxed by default, and outgoing connections need com.apple.security.network.client, which the template omits. Add it to both macos/Runner/DebugProfile.entitlements and Release.entitlements, keeping them in step.
solid answer
~40 sThe macOS template signs the app with **App Sandbox** on, which the Mac App Store requires. A sandboxed app can only do what its **entitlements** allow. The template ships two files: `macos/Runner/DebugProfile.entitlements`, with `app-sandbox`, `cs.allow-jit` and `network.server` so the Flutter tool can talk to a debug or profile app, and `Release.entitlements`, with only `app-sandbox`. Neither contains `com.apple.security.network.client`, so outgoing HTTP fails with a `SocketException` saying `Operation not permitted` until you add it to both files. Plugins need their own: `file_selector` needs `files.user-selected.read-only` or `read-write`. A second trap is incoming connections: `network.server` exists only in DebugProfile, so a local server works in debug and fails in release. Edit the files directly, because Xcode's capabilities UI may change only one of them.
code
xml · 12 lines<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>go deeper
Recall that Flutter macOS apps are sandboxed and need network.client in the entitlement files to call an API.
Explain the two entitlement files, what the DebugProfile extras are for, and why incoming connections can work only in debug.
Show you audit plugin entitlements, keep both files consistent and test release builds on macOS before shipping.
Weigh Mac App Store distribution and its sandbox against direct distribution, and the permissions each product feature commits the app to.
## The sandbox and entitlements macOS apps distributed through the Mac App Store must run in the **App Sandbox**, which denies access to the network, files outside the app's container, the camera, the microphone and more unless the app declares an **entitlement** for it. Flutter's macOS template turns the sandbox on from the start, so the same rules apply during development. Entitlements live in property-list files that Xcode signs into the app. The template has two, one per group of build configurations: | File | Used for | Template contents | |---|---|---| | `macos/Runner/DebugProfile.entitlements` | debug and profile | `com.apple.security.app-sandbox`, `com.apple.security.cs.allow-jit`, `com.apple.security.network.server` | | `macos/Runner/Release.entitlements` | release | `com.apple.security.app-sandbox` | The extra debug entries exist for the tooling: JIT for the Dart VM in debug mode, and an incoming-connection permission so `flutter run` can talk to the app. ## Symptom one: outgoing requests fail everywhere Neither file grants `com.apple.security.network.client`. An app that calls an API fails with an error such as: ```text SocketException: Connection failed (OS Error: Operation not permitted, errno = 1) ``` The fix is to add the key to **both** files: ```xml <key>com.apple.security.network.client</key> <true/> ``` Because the sandbox is also on in debug, this appears on the first run, which makes it easy to spot. ## Symptom two: works in debug, fails in release `com.apple.security.network.server` is present only in `DebugProfile.entitlements`. If the app itself accepts incoming connections, for example a small local server for a companion device, it works in debug and profile and fails in release. Add `network.server` to `Release.entitlements` as well when the feature needs it. ## Plugins bring entitlement requirements - `file_selector` needs `com.apple.security.files.user-selected.read-only` or `...read-write`, depending on whether the app writes files. - Camera and microphone plugins need the sandbox's device entitlements; with the **Hardened Runtime** also enabled, some resources need a second, runtime entitlement. - A plugin's README usually lists what it needs on macOS. ## Rules for editing 1. **Edit the files directly.** Xcode's capabilities editor may update only one of the two files, or create a new file and switch every configuration to it. 2. **Make the same change in both files** unless there is a specific reason not to. 3. **Keep the DebugProfile extras** (`allow-jit`, `network.server`); removing them breaks debug and profile runs. 4. **Test a release build** before shipping; only it uses `Release.entitlements`. ## Diagnosing a sandbox failure 1. Read the error: `Operation not permitted` from a socket or file call on macOS points at the sandbox, not at your server or path. 2. Check which build configuration failed; a debug-only success suggests an entitlement present only in `DebugProfile.entitlements`. 3. Compare both entitlement files with the plugin's documented requirements. 4. Rebuild after editing; entitlements are signed into the app at build time, so a hot restart does not pick them up. ## Worked example A small-shop invoice tool syncs invoices with a web service and exports PDFs to a folder the user picks. It needs `network.client` and `files.user-selected.read-write` in both files. The team adds them, runs `flutter build macos`, and checks export and sync in the release build.
- A Flutter macOS app's embedded local server works under flutter run but not in the release build. Why?Incoming connections need `com.apple.security.network.server`, which the template grants only in `DebugProfile.entitlements` so the Flutter tool can reach the app. `Release.entitlements` lacks it, so the release build's sandbox blocks the listener. Add the key to `Release.entitlements` if the feature needs it.
- Could a Flutter team just turn the App Sandbox off on macOS?For apps distributed outside the Mac App Store it is technically possible, but the Mac App Store requires the sandbox, and removing it gives up the protection it provides. Keeping the sandbox and declaring the specific entitlements the app needs is the normal approach.
saying these in an interview costs you the question
- A Flutter macOS app has network access by default like a mobile app.
- network.server in DebugProfile also covers outgoing HTTP calls.
- Editing only Release.entitlements is enough for every build.
- Removing allow-jit from DebugProfile has no effect.
- The Xcode capabilities editor always keeps both entitlement files in sync.