Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Troubleshooting

Start with the two commands that answer most questions:

netscope status
sudo netscope doctor

status shows whether the daemon is reachable and what each profile currently has attached. doctor checks seven things: root, kernel, cgroup v2, tools, daemon, state and config, and profile runtime. Both exit non-zero on failure; see CLI reference. Run doctor with sudo; without root the root check fails and doctor exits 1.

Checklist

SymptomCheckLikely cause and fix
daemon not running (exit 3)systemctl status netscopedStart it: sudo systemctl start netscoped. If it exits immediately, read journalctl -u netscoped -n 50.
permission denied (exit 4)id -nG includes netscopeAdd the user and log in again: sudo usermod -aG netscope "$USER". A new shell is not enough; the session must be new.
doctor fails on the kerneluname -rKernel older than 5.13 cannot hold an exec. Upgrade the kernel.
doctor fails on cgroupsstat -fc %T /sys/fs/cgroupNot cgroup2fs means a v1 or hybrid hierarchy. Boot with unified cgroup v2.
nft: command not foundcommand -v nftInstall nftables.
ip: command not foundcommand -v ipInstall iproute2.
Operation not permitted from nftables or cgroupssystemctl cat netscopedThe daemon is not running as root or lost a required privilege. Run the shipped unit; do not drop capabilities it needs.
Config change is ignoredjournalctl -u netscoped -n 50The daemon reads the file at startup. Restart it. An unknown key is rejected.
add says the profile existsnetscope listNames are unique. Remove the old profile or choose another name.
add fails at the profile limitnetscope listAt most 32 profiles. Remove unused ones.
App is not scopednetscope status, then cat /proc/<pid>/cgroupThe app was never matched, or the poll has not run yet. Check the target name and wait one poll interval; a late attach marks existing sockets. Restart only if the process is not matched at all.
App is scoped but an old connection still worksnetscope status shows lateExisting sockets are marked and should follow the profile. Check the daemon log for mark profile=... error=...; restart the app if a descriptor could not be marked.
Steam game is not scopednetscope status after launching the gameAdd the profile before launching, and launch the game through Steam. Restart Steam if it was already running.
Wine/Proton game is not scopednetscope status shows pre-open, mixed, late, or nonePoint --wine at the .exe the loader actually opens, using an absolute path. Add the profile before launching. A late attach marks existing sockets, so they follow the profile; restart only if the log reports a mark failure.
Two consumers need one appnetscope status and netscope resolve --process <name>Use netscope open with each consumer so both share one profile and cgroup. A second netscope add for the same target and uid is refused with target already scoped.
Process-name target is not scopednetscope status shows name:<name>, cat /proc/<pid>/commThe name must match comm or an argv basename, case-insensitively. Cross-check the real name with ps -o comm= -p <pid>. A late attach marks existing sockets, so they follow the profile; restart only if the log reports a mark failure.
Route profile has no connectivityip link show <iface>, ip route show table <table>The interface is down or has no route. The blackhole is doing its job. Bring the tunnel up.
Route profile works, then dies when the VPN dropsThis is intendedThe blackhole rejects traffic while the interface is down. Restore the tunnel or remove the profile.
LAN devices unreachable in route modeLook for --include-lanBy default LAN traffic bypasses the tunnel. If the app must reach the LAN through the tunnel, add the flag. Conversely, if you added --include-lan and the tunnel does not carry LAN, remove it.
IPv6 stops workingnetscope statusRoute mode drops IPv6 unless --allow-ipv6 is set. Add it only if the tunnel carries IPv6.
DNS fails in filter modeThe profile’s --allow-cidr listAllow the resolver’s address. Loopback resolution through a local stub may still work, but the stub’s upstream query is a separate process.
DNS fails in route modeTunnel DNS configurationnetscope does not configure DNS. Push a resolver through the tunnel or set one manually.
Stale tables or rules after a crashsudo nft list tables, ip rule showStop the daemon, then run sudo netscope cleanup --all. See Cleanup.
cleanup exits 3systemctl is-active netscopedCleanup refuses to run while the daemon is active. Stop it first.

The daemon will not start

systemctl status netscoped
journalctl -u netscoped -n 100 --no-pager

Common causes:

  • Unknown config key. The config parser rejects unknown fields. Compare /etc/netscope/config.toml with Configuration.
  • cgroup root outside the cgroup2 mount. cgroup_root must be under /sys/fs/cgroup.
  • State file unreadable or from a newer version. Restore a backup or, if you accept losing profile definitions, move the file aside and run sudo netscope cleanup --all before starting.
  • Socket path not writable. /run/netscope must exist and be writable by root. The shipped unit creates it.

The app is not scoped

Check in this order:

  1. netscope list confirms the profile exists and is enabled.
  2. netscope status shows a process in PIDS while the app runs.
  3. cat /proc/<pid>/cgroup contains /netscope/<profile>.
  4. sudo nft list table inet netscope_<profile> shows the expected rules.

If PIDS is empty, the daemon never matched the process. Typical reasons:

  • The executable path resolved differently than you expect. Use readlink -f /path/to/app and add that path.
  • The app is a script or launcher that execs a different binary. Select the binary that actually opens sockets, or select the launcher if its children stay in the same cgroup.
  • The app was already running before the profile existed and the poll fallback did not catch it. Restart it.
  • A security policy blocks fanotify. doctor reports the attach source; late attachment is reported as late.

If PIDS is populated but traffic still escapes, the remaining causes are usually a socket whose descriptor could not be marked (check the log), DNS handled by another process, or traffic generated by the kernel rather than the app. See Security.

Wine and Proton

A --wine profile attaches when Wine opens the PE, and status reports pre-open. If the game runs but PIDS stays empty:

  • netscope status should show wine:/path/to/game.exe. A file under steamapps/common/ and its copy under steamapps/compatdata/<appid>/pfx/drive_c/ are different files. Select the one Wine actually opens, and keep the path absolute.
  • The attached process must be a Wine process whose command line names the PE: wine, wine64, wine-preloader, wine64-preloader, or a basename containing wine-preloader. wineserver is never attached; it may open the PE for a loader, but it is shared across Wine applications. A non-Wine process that opens the PE is allowed and left unscoped by design.
  • Add the profile before launching the game. If the daemon had to fall back to polling, status shows late; existing sockets are marked at attach, so they follow the profile. Restart only if the log reports a mark failure.
  • Flatpak, Snap, and unusual filesystems are not tested. If the fanotify mark cannot be placed, status reports fanotify unavailable; poll-only, and the poll fallback attaches late and marks existing sockets. It also reports executable missing when the PE path no longer exists. Report a reproducible case with a support bundle.

Route mode has no connectivity

ip link show tun0
ip rule show
ip route show table 20000
nft list table inet netscope_<profile>
  • No default dev tun0 route means the interface is down or the gateways are wrong. If the tunnel needs a next hop, pass --gateway or --gateway6.
  • The blackhole route at metric 1000 is expected. It is only used when the real route is absent.
  • Test from the same terminal and user that launches the app. A different process is not in the profile.
  • Confirm the app is attached and that its connections were opened after attachment.

Cleanup

Use cleanup only when the daemon cannot remove its own state:

sudo systemctl stop netscoped
sudo netscope cleanup --all
sudo systemctl start netscoped

cleanup --all removes netscope’s nftables tables, policy rules, routes, and cgroups. It refuses to run while the daemon is reachable, because the daemon’s health loop would recreate the rules within about ten seconds. --purge also removes the persisted profile state and /etc/netscope/config.toml; use it only when you intend to start over.

Before reporting a bug

sudo netscope doctor --json
sudo netscope support-bundle --include-logs --include-config

Review the bundle, then attach it to the issue. Include the exact command, expected behavior, actual behavior, and the profile’s consumers and policies. See Support bundle.