#3491·go-libp2p

AutoNAT v2 dialerHost should not have the UDP black hole detector

Author: sreneCreated Apr 23, 2026Updated Apr 28, 2026

This issue distills findings from a systematic cross-implementation evaluation of AutoNAT v2, conducted by ProbeLab. The final report of the investigation is available in the following link.

The AutoNAT v2 dialerHost shares the main host's UDP black hole counter in read-only mode config.go#L240-L246. Read-only mode treats any state other than Allowed as Blocked black_hole_detector.go#L254-L262, so when the main host is in Probing (zero history), the dialerHost refuses every QUIC dial-back with E_DIAL_REFUSED.

Observed behaviour:

  • Fresh servers, low-traffic nodes, and isolated testbeds can stay in Probing → every QUIC dial-back is refused.
  • E_DIAL_REFUSED is discarded from v2 confidence by AddRefusal (it does not call AddOutcome), so the client's QUIC address doesn't flip to Unreachable — but it never accumulates positive evidence either, and stays stuck in Unknown.
  • AutoNAT v1 had the same problem and was fixed in [#2529](https://github.com/libp2p/go-libp2p/pull/2529) by disabling the detector on the v1 dialer entirely.

Proposal: apply the v1 approach — pass nil counters to makeAutoNATV2Host() so the detector doesn't run on the dialerHost. The dialerHost only dials addresses clients explicitly request to test; the detector has no useful role there.