Terminal Sandbox Issue Linux

Here’s a fix that I worked out in a chatgpt session over a couple of hours. It amalgamates elements of solutions posted by others on this forum. I do not pretend to understand all of it. So please verify and use at your own discretion.

The rest of this post was drafted by chatgpt, but I read through if carefully before posting and it does indeed reflect the fix that I implemented .


Ubuntu 24.04 (AppArmor 4.x) + kernel 6.2+ (e.g. 6.8): “Terminal sandbox could not start” / Step 2.5/7 loopback NETLINK_ROUTE bind fails

Symptoms / logs typically show:

  • Cursor popup: “Terminal sandbox could not start… AppArmor…”

  • ~/.config/Cursor/logs/.../exthost.log:
    Failed to apply sandbox: Step 2.5/7 (loopback setup) ... failed to bind NETLINK_ROUTE socket

  • kernel audit:
    apparmor="DENIED" ... profile="cursor_sandbox" ... family="netlink" sock_type="raw" ... denied="bind"

Root cause (in this failure mode): Cursor’s shipped /etc/apparmor.d/cursor-sandbox is incomplete on Ubuntu 24.04+ and blocks the helper from doing rtnetlink/loopback setup (and sometimes userns / newuidmap/newgidmap bits). See related threads:

Below is an upgrade-resistant fix that avoids global sysctl weakening and avoids “allow-all”.


0) Confirm you have this exact failure mode

grep -R "Failed to apply sandbox" -n ~/.config/Cursor/logs | tail -n 60
sudo journalctl -k -b --since "10 minutes ago" --no-pager | \
  grep -iE 'apparmor="DENIED"|cursor_sandbox|unprivileged_userns' | tail -n 200

If you see Step 2.5/7 (loopback setup) + netlink raw bind denied, proceed.


1) Make the AppArmor profile upgrade-resistant (dpkg diversion)

Rationale: Cursor updates can overwrite /etc/apparmor.d/cursor-sandbox without prompting. dpkg-divert preserves your maintained file while still letting the vendor’s new profile install alongside as .distrib for diff/merge. The .predivert.date file is your backup.

sudo cp -a /etc/apparmor.d/cursor-sandbox /etc/apparmor.d/cursor-sandbox.predivert.$(date +%F_%H%M%S)

sudo dpkg-divert --local --rename --add \
  --divert /etc/apparmor.d/cursor-sandbox.distrib \
  /etc/apparmor.d/cursor-sandbox

Then base your maintained file on the vendor profile:

sudo cp -a /etc/apparmor.d/cursor-sandbox.distrib /etc/apparmor.d/cursor-sandbox

2) Patch /etc/apparmor.d/cursor-sandbox structurally (minimal edits)

Rationale: keep the vendor file mostly intact, add only what’s needed for Ubuntu 24.04/AppArmor 4.x and future helper renames, and delegate permissions to a local include.

Edit:

sudoedit /etc/apparmor.d/cursor-sandbox

Make these changes:

(a) Add at top (AppArmor 4.x compatibility)

abi <abi/4.0>,
include <tunables/global>

(b) Attach profiles to both helper names (rename-proof)

Change the profile lines to:

profile cursor_sandbox /usr/share/cursor/resources/app/resources/helpers/{cursor-sandbox,cursorsandbox} {
...
}

profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox} {
...
}

(c) Ensure userns, is enabled inside both blocks

Uncomment/add the following line to both blocks:

  userns,

(d) Make the mr rule match the brace path in both blocks

  /usr/share/cursor/resources/app/resources/helpers/{cursor-sandbox,cursorsandbox} mr,

and

  /home/*/.cursor-server/bin/*/*/resources/helpers/{cursor-sandbox,cursorsandbox} mr,

(e) Add a local include in both blocks

Rationale: keep your policy deltas in one place.

  #include if exists <local/cursor-sandbox>

Note: #include is an AppArmor preprocessor directive (not a comment).

(f) If you see capname="net_admin" denials in journalctl, add the following line to both profile blocks; otherwise you can omit it.

capability net_admin,

3) Put the actual missing permissions in /etc/apparmor.d/local/cursor-sandbox

Rationale: fix Step 2.5/7 (netlink) and common userns/newuidmap IPC needs without “allow all”.

sudo install -d -m 0755 /etc/apparmor.d/local

sudo tee /etc/apparmor.d/local/cursor-sandbox >/dev/null <<'EOF'
  # Required on Ubuntu 24.04+ restricted userns
  userns,

  # Required for Step 2.5/7 loopback/rtnetlink setup
  network netlink raw,
  network netlink dgram,

  # Commonly required for sandbox IPC
  network unix stream,
  network unix dgram,

  # newuidmap/newgidmap may need this
  capability dac_override,

  # If you create cursor-system profile below:
  signal (send, receive) peer=cursor-system,
EOF

4) Optional: add cursor-system to avoid disabling Ubuntu’s userns restriction globally

Rationale: some setups hit Ubuntu’s unprivileged_userns mediation; this avoids turning off kernel.apparmor_restrict_unprivileged_userns system-wide. This is “unconfined” for Cursor itself (which is typically unconfined anyway), but explicitly allows userns while keeping the global hardening on.

sudo tee /etc/apparmor.d/cursor-system >/dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile cursor-system "/usr/share/cursor/cursor" flags=(unconfined) {
  userns,
}
EOF

5) Reload AppArmor profiles

sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox
sudo apparmor_parser -r /etc/apparmor.d/cursor-system
sudo aa-status | grep -i cursor

Restart Cursor.


6) Validate (no new denials)

sudo journalctl -k -b --since "2 minutes ago" --no-pager | \
  grep -iE 'cursor_sandbox|apparmor="DENIED"|unprivileged_userns'

If clean and popup is gone, you’re done.


7) After each Cursor upgrade: diff & merge safely

Rationale: vendor may add new required rules in future; diversion keeps both versions available.

diff -u /etc/apparmor.d/cursor-sandbox.distrib /etc/apparmor.d/cursor-sandbox | less

Avoid the chattr +i /etc/apparmor.d/cursor-sandbox approach: it can cause apt/dpkg upgrade failures or leave the package half-configured. dpkg-divert is the packaging-native way to prevent overwrites while still receiving upstream changes for review.