Scanner Resource Exhausted
A probe failed because the SCANNER HOST ran out of a local resource — file descriptors, socket buffers, local ports, or the kernel neighbour (ARP/NDP) table — or was blocked locally. Such a probe says nothing about the target but is indistinguishable from a closed port, so the scanner fails the whole job instead of recording results that would write false open-to-closed changes into the audit trail.
Fields & columns
| Name | Description |
|---|---|
kind | What ran out: fd, buffers, local_ports, local_firewall, interface_down, neighbour_table, or unknown (an errno the scanner does not classify — the raw text is in the message) |
message | The scanner's full report: SCANNER_RESOURCE_EXHAUSTED(kind), the cause and address, how many of the planned probes had run, and the remedy |
How to
Diagnose
- Read the job error's message — it names the resource, the errno and the remedy
- On the scanner host, read the startup self-check lines: journalctl -u mipo-scanner | grep selfcheck
- For kind=neighbour_table, read the kernel counters on the HOST: cat /proc/net/stat/arp_cache (and ndisc_cache) — the table_fulls and unresolved_discards columns
- For kind=fd, compare the process limit with the worker count: grep "Max open files" /proc/$(pgrep -f mipo-scanner)/limits
Fix on the scanner host
- Raise the limit that matches the kind: LimitNOFILE via a systemd drop-in (fd), net.ipv4.neigh.default.gc_thresh3 and its ipv6 twin (neighbour_table), net.ipv4.ip_local_port_range (local_ports), or the host socket-buffer limits (buffers), OR
- Lower MIPO_SCAN_CONCURRENCY / raise MIPO_SCAN_TIMEOUT in /etc/mipo-scanner.env — the load is the probe RATE, roughly concurrency ÷ timeout
- Restart: sudo systemctl restart mipo-scanner, then confirm the selfcheck lines report enough headroom
Clear the error
- Acknowledge the job error — the job is terminal and re-running it on an unfixed host would fail again
- The alarm resolves itself once that scanner completes its next job
Gotchas
- The scan results from a failed job are NOT used as a baseline and cannot close a port — the reconciler excludes failed jobs from participation. A raw job still keeps the genuine open ports it had already reported.
- A delta (compacted) job sends NO receipt when it fails this way, so the next scan compares against the previous baseline.
- The neighbour-table counters are HOST-WIDE: another workload overflowing the table also fails this job. That is deliberate — if the table overflowed at all, this scan's accuracy was at risk.
- Neighbour-table overflow is only detectable from the host's own network namespace. A scanner in a container namespace logs "not verifiable here" at startup and cannot catch it — run such a scanner with --network host.
- Conntrack is NOT one of these kinds. The conntrack table is checked only at STARTUP, where a table too small for the configured probe rate makes the scanner refuse to start. A conntrack table that fills DURING a scan drops the SYN before it leaves the host, so the probe just times out like a dead host — which is exactly why the startup check is sized for the worst case rather than relying on per-probe detection. See docs/operations/scanner-install.md "Kernel limits for fast scans".
- kind=unknown means the scanner met an errno it does not classify. It fails the job on purpose: an unexplained error must never be recorded as a closed port. The raw errno is in the message.
- The scanner REFUSES TO START when its configured probe rate cannot fit a kernel limit, so a host that trips this at startup never scans at all — check journalctl for the refusal.
API calls (2)
| Method | Path | Description |
|---|---|---|
| GET | /api/health/job-errors | List active job errors, including this class |
| POST | /api/health/job-errors/:stateId/repair | action=acknowledge |
Related
- Job Errors Overview — Category model
- Scanners — Per-scanner concurrency and timeout settings