GyulyVGC/sniffnet · info · LatencyStatus::Failed

No reply

Error message

No reply

What it means

In measure_latency (src/networking/types/latency.rs:50), after sending PING_COUNT probes, if zero replies were received the function builds LatencyStatus::Failed from the last recorded error, defaulting to the literal 'No reply' via unwrap_or_else when last_error is None. Each loop iteration records SurgeError::Timeout or breaks on other errors, so 'No reply' is the defensive fallback meaning: every ping attempt failed without a captured error message (e.g. PING_COUNT iterations produced no reply and no stored error), and no RTT value can be shown.

Source

Thrown at src/networking/types/latency.rs:50

    let mut sum = Duration::ZERO;
    let mut received: u32 = 0;
    let mut last_error = None;
    for _ in 0..PING_COUNT {
        match pinger.ping(next_sequence(), &PING_PAYLOAD).await {
            Ok((_, latency)) => {
                sum += latency;
                received += 1;
            }
            Err(error @ SurgeError::Timeout { .. }) => last_error = Some(error.to_string()),
            Err(error) => {
                last_error = Some(error.to_string());
                break;
            }
        }
    }

    match received {
        0 => LatencyStatus::Failed(last_error.unwrap_or_else(|| "No reply".to_string())),
        n => LatencyStatus::Measured(sum / n),
    }
}

fn client_for(ip: IpAddr) -> Result<Arc<Client>, String> {
    let (cell, kind) = match ip {
        IpAddr::V4(_) => (&IPV4_CLIENT, ICMP::V4),
        IpAddr::V6(_) => (&IPV6_CLIENT, ICMP::V6),
    };

    if let Some(client) = cell.get() {
        return Ok(Arc::clone(client));
    }

    let client = latency_client(kind)?;
    Ok(Arc::clone(cell.get_or_init(|| client)))
}

View on GitHub (pinned to 48b0575dc0)

Solutions

  1. Verify the host answers ICMP at all: `ping <ip>` from a terminal — if that also fails, the latency column can never show a value (firewall/host policy), which is expected behavior.
  2. Allow ICMP echo request/reply in the remote host firewall or cloud security group if you control it.
  3. Check local connectivity/routing first (default route present, VPN split tunnel excluding the target).
  4. Retry after network changes — the status is per measurement, later attempts can succeed; timeouts are capped by PING_TIMEOUT.
  5. If every host shows Failed including 8.8.8.8, suspect local privileges/firewall instead (see error 10) or an OS-level ICMP block.
Defensive patterns

Strategy: fallback

Try / catch

// Failed('No reply'/Timeout) is informational — degrade gracefully
match measure_latency(ip).await {
    LatencyStatus::Measured(d) => render(d),
    LatencyStatus::Failed(reason) => render_dash_with_tooltip(reason), // don't retry automatically
    LatencyStatus::Measuring => render_spinner(),
}

Prevention

When it happens

Trigger: All probes to a host are lost: destination drops ICMP echo (firewalled), intermediate network filters ICMP, host is offline/unroutable — normally these surface as Timeout strings carried in last_error; 'No reply' itself appears when the loop completed with received == 0 and last_error stayed None, e.g. zero-iteration edge cases or errors not recorded. Result: the latency column renders the Failed text ('No reply' or the last surge error).

Common situations: Pinging Windows hosts (ICMP often filtered), cloud servers behind security groups denying ICMP, pinging during connection loss/airplane mode, DNS-resolved IPv6 targets on an IPv4-only network, hosts that rate-limit ICMP; also all-Timeout runs where the displayed text is the surge Timeout message rather than 'No reply' — same Failed state.

Related errors


AI-assisted analysis of GyulyVGC/sniffnet@48b0575dc0 (2026-08-16). Data as JSON: /api/errors/e64beeb5fadf9aba. Report an issue: GitHub.