Troubleshooting, Pitfalls, and Result Verification

The Anatomy of False Negatives

Nmap's absence of evidence is never evidence of absence. The most insidious false negatives stem from packet pathologies that masquerade as network quietude.

Filtered versus dropped packets create divergent diagnostic signatures. A filtered port elicits an ICMP admin-prohibited or TCP RST from a firewall, which Nmap interprets correctly. A dropped packet, however, vanishes silently—indistinguishable from an open port with no listener, or from a firewall configured to DROP without response. When you see open|filtered, Nmap confesses its uncertainty: the port failed to respond within the probe's timeout window, but no rejection was received. This ambiguity dominates UDP scanning (-sU) by design, since UDP lacks acknowledgment semantics. An actually open UDP service may simply not respond to your probe payload, while a filtered UDP port absorbs it identically. The only disambiguation is payload specificity: if Nmap's default DNS probe (port 53) receives no answer, try nmap -sU -p 53 --script dns-recursion <target> with a valid query, or manually inject with echo -n -e '\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x06google\x03com\x00\x00\x01\x00\x01' | nc -u <target> 53.

Rate limiting compounds the problem. Target hosts, intermediate IDS, or even your own ISP may throttle ICMP responses or SYN-ACK rates. Nmap's dynamic timing (-T4, -T5) assumes aggressive scanning suits the path; it does not. When Nmap reports 0/1000 ports open on a known-live host, inspect nmap --packet-trace output for retransmissions exceeding --max-retries. Escalating retry counts with static --max-rtt-timeout values suggest path congestion, not host inactivity.

TCP window=0 responses constitute a subtle trap. Some services—particularly embedded systems and hardened kernels—acknowledge the SYN with SYN-ACK, win=0, then never complete the handshake. Nmap typically marks these open, yet the service may be intentionally unresponsive or resource-starved. The port is technically open at the TCP state machine level, but functionally useless. Cross-verify with nc -vz <target> <port> observing whether data transfer succeeds, or capture the full handshake with the tcpdump filter discussed below.

False Positive Patterns: When Infrastructure Lies

Modern network architectures actively deceive port scanners. Load balancers with SYN proxying or DSR (Direct Server Return) configurations may acknowledge SYNs for backend pools that are down, presenting open ports to no available service. The tell: consistent open results with immediate connection drops during application negotiation, or wildly varying TTL values in returned packets (nmap --reason --packet-trace exposes this).

Transparent proxies and CDN edge nodes intercept and respond to probes before reaching the origin. A http-proxy script result with banner mismatches—Apache presented where Nginx is expected, or impossible version strings—warrants suspicion. Honeypots amplify this: Kippo, Cowrie, and commercial deception platforms emulate service banners with characteristic tells (overly verbose SSH versions, immediate root shells, or protocol violations). When ssh-hostkey scripts return keys with suspiciously low bit lengths or duplicate across non-related subnets, you're likely facing instrumentation, not infrastructure.

The 'All Ports Filtered' Diagnostic

An apparently simple result—1000 ports filtered—demands structured interrogation:

| Scenario | Symptoms | Verification | |----------|----------|--------------| | Target down/no route | ARP failures, ICMP unreachable from gateway | ping, traceroute to adjacent hosts, nmap -sn host discovery | | Stateful firewall block | Consistent ICMP admin-prohibited, uniform timing | Vary source port (-g), fragment (-f), or protocol (-sO) | | Scanner misconfiguration | Self-consistent but absurd results (e.g., localhost filtered) | nmap 127.0.0.1, check interface selection (-e) |

The VPN MSS clamping failure merits emphasis. Scanning through tunnels without Path MTU awareness generates fragmented or oversized packets that middleboxes drop. If all filtered appears exclusively through VPN interfaces, test with nmap -sS --mtu 1400 or enforce clamping at the tunnel interface. IPv6 scanning fails analogously: link-local address selection (fe80::/10) requires explicit interface binding (nmap -e eth0 fe80::1%eth0), and many Nmap scripts default to IPv4-only behavior without -6. The error Failed to resolve given IPv6 hostname often indicates missing -6 flag or unreachable IPv6 paths, not target absence.

Performance Troubleshooting: Bottleneck Isolation

Scan duration explosions typically trace to three domains. DNS resolution stalls when Nmap reverse-resolves every discovered IP (-n disables this; -R forces it). For large ranges, nmap -n is mandatory, with external massdns handling name operations if required.

RTT calculation failures emerge in satellite, cellular, or congested paths. Nmap's initial RTT estimate (undocumented, typically ~100ms at -T3) may underestimate actual latency, triggering premature retransmissions that compound congestion. Explicit calibration with nmap --initial-rtt-timeout 2s --max-rtt-timeout 5s for high-latency paths prevents this spiral.

Script execution bottlenecks appear with --script vuln or http-enum against large host lists. The engine executes serially per host; parallelization requires nmap --script-timeout 10m or decoupling to nmap for discovery and nse scripts via nmap --script <script> --script-args=newtargets in secondary passes.

Verification Methodologies: Nmap as Hypothesis

Treat every Nmap result as a falsifiable claim. The verification toolchain:

Cross-scanning with netcat validates TCP state independently:

# Nmap claims port 443/tcp open; verify with manual negotiation
nc -vz -w 5 <target> 443          # Connect timeout or success?
echo "QUIT" | nc -q 1 <target> 443  # Protocol response validation

tcpdump packet capture confirmation provides ground truth for Nmap's interpretation. Capture filter syntax optimized for scanner verification:

# Capture all TCP probes and responses for target 192.0.2.10
sudo tcpdump -ni eth0 -w nmap_verify.pcap \
  'host 192.0.2.10 and (tcp[13] & 2 != 0 or tcp[13] & 16 != 0 or icmp[icmptype] == icmp-unreach)'

# Analyze: did SYN receive SYN-ACK, RST, or silence?
tcpdump -r nmap_verify.pcap -nn -tttt -v 'tcp port 443'

This captures SYN flags (tcp[13] & 2), SYN-ACK/RST (tcp[13] & 16 for ACK—refine with additional bitmasking), and ICMP unreachables. Compare against Nmap's --packet-trace log line-by-line.

Secondary tool correlation breaks tool-specific bias. masscan with its separate TCP stack may reach ports Nmap misses due to differing retransmission logic; zgrab2 or openssl s_client validates TLS handshakes that ssl-cert scripts misinterpret. For UDP, unicornscan with custom payloads (-mU -r 3000) may elicit responses Nmap's default probes miss.

When Nmap Is Fundamentally Wrong-Scale

Nmap's architectural assumptions—reliability, completeness, scriptability—become liabilities at scale. Masscan sacrifices accuracy for speed, transmitting without awaiting replies, making it suitable for internet-wide census (estimated 45 minutes for /0 at 100kpps). Zmap optimizes further for research use cases, achieving line-rate performance with minimal state tracking. Neither replaces Nmap's service detection; they complement it as discovery phases.

Specialized protocol scanners—ike-scan for ISAKMP, onesixtyone for SNMP community brute-forcing, rdp-sec-check for RDP security negotiation—outperform NSE scripts in depth for single-protocol reconnaissance. The professional rigor is knowing when Nmap's generality introduces unacceptable error rates, and selecting the precise instrument for the measurement required.

Every output line demands this question: what observation would contradict this conclusion, and have I sought it?