## TL;DR
Masscan crafts its own packets, which needs raw socket access, and the OS said no. Run it with elevated privileges (root or the NET_RAW capability), or fall back to `--unprivileged` mode, which uses normal TCP connections at a lower rate. One of those two clears this error every time.

```text
FAIL: Operation not permitted
```

## Use this when
- Masscan exits immediately with this error on a tester box you control.
- You are in a container, a hardened VM, or a locked-down laptop where raw socket rights may be stripped.

## Not for this skill when
- Masscan starts but finds no hosts. That is routing or scope, not permissions.
- The error appears mid-scan. That points at a dropped privilege or a network namespace change instead.

## Steps
1. Confirm the error is permissions, not syntax: `masscan --rate 1000 -p80 target.example.com --unprivileged`. Verify: the scan runs, slower, which proves the config is fine and only raw sockets are blocked.
2. Preferred fix on a box you administer: run with sudo, `sudo masscan ...` with your normal flags. Verify: the FAIL line disappears and packets go out.
3. In Docker without full sudo, add just the capability: launch the container with the NET_RAW capability added. Verify: masscan starts inside the container without the FAIL error.
4. Check for mandatory-access systems blocking raw sockets even as root: `dmesg | grep -i denied` on SELinux or AppArmor boxes. Verify: no denial lines appear when masscan starts.
5. If you must stay unprivileged, accept the tradeoff: `--unprivileged` caps your rate and cannot do SYN scans. Verify: the engagement plan's timing still holds at the lower rate before you commit to it.

## Variant phrasings
### masscan operation not permitted root
The privilege-shaped search.
### masscan raw socket permission denied docker
Container-specific phrasing.
### masscan fails to start permission error
The generic startup phrasing.

Compatibility: masscan 1.3.x on Linux. `--unprivileged` exists in all recent builds.

## Why it happens
Masscan bypasses the kernel TCP stack and builds packets itself for speed, which requires the NET_RAW capability on Linux. Sandboxed environments (containers, some CI runners, locked-down laptops) strip that capability, so the first raw socket call fails and masscan aborts before sending anything.

## Edge cases / pitfalls
- `--unprivileged` in a scan plan that assumed SYN-scan speed will blow the time budget. Re-estimate the rate, often an order of magnitude slower, and tell the test lead.
- Running the whole engagement as root to dodge this is lazy hygiene. Prefer the single capability or a dedicated scan user with sudo limited to masscan.
- Cloud provider networks sometimes filter crafted packets even with correct privileges. If masscan starts but sees nothing, suspect the virtual network, not the box.
- Some distributions ship masscan without the needed capability on the binary itself; setting it on the binary is an alternative to sudo.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_hQKqKUGnXXlexoekeTTyfw
