# How to Test Tailcat Connectivity with `tailcat ping`

> Test Tailcat connectivity using tailcat ping. Send a discovery ping to check round-trip latency and see if your connection is direct or uses a DERP relay.

- Repository: [Tailscale/tailcat](https://github.com/tailscale/tailcat)
- Tags: how-to-guide
- Published: 2026-08-30

---

**Run `tailcat ping <addrblob>` to send a lightweight discovery ping that reports round-trip latency and confirms whether the connection traverses a DERP relay or uses a direct path.**

The `tailscale/tailcat` repository includes a dedicated subcommand for validating network paths between nodes. When you need to test Tailcat connectivity, the `tailcat ping` utility offers a reliable method to verify reachability, measure latency, and diagnose whether your traffic requires relay traversal. This command leverages Tailscale's discovery protocol to provide immediate feedback on your mesh network's health.

## Understanding the tailcat ping Mechanism

The ping implementation resides in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) within the `clientPingMode` function. When executed, the client builds a `tailcat.Client` instance configured with the DERP map URL and optional authentication keys (lines 68-76). The core logic invokes `Client.DiscoPing`, which transmits a specially crafted **meow** packet across the DERP network. The target server responds with a **meowed** acknowledgment, allowing the client to calculate precise round-trip time and identify the responding endpoint (lines 83-98).

## Interpreting tailcat ping Output

The command prints structured results indicating both latency and network path. A typical response follows the format `pong in 12.3ms via DERP(2)` when traversing a relay, or `pong in 1.4ms via 192.0.2.1:12345` when a direct connection is established. This output distinguishes between relayed and direct connectivity, critical for diagnosing NAT traversal behavior.

## Running tailcat ping Commands

### Basic Connectivity Verification

To perform a standard reachability test, first start a Tailcat server to generate an address blob, then invoke the ping command:

```bash

# Start server and capture address

$ tailcat --serve=0 > /tmp/addrblob &
$ ADDRESS=$(cat /tmp/addrblob)

# Test basic connectivity

$ tailcat ping "$ADDRESS"
pong in 9.8ms via DERP(2)

```

### Testing Direct Path Establishment with --until-direct

For scenarios requiring validation of direct connectivity without DERP relays, use the `--until-direct` flag. This repeatedly sends discovery pings until either a direct path is established or the specified timeout expires:

```bash
$ tailcat ping --until-direct --timeout=30s "$ADDRESS"
pong in 1.1ms via 10.0.0.2:12345

```

This approach is particularly valuable when testing firewall rules or NAT hairpinning configurations.

## Automated Testing in the Repository

The `tailscale/tailcat` codebase includes comprehensive integration tests in [`cmd/tailcat/ping_test.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/ping_test.go) (lines 12-41). These tests validate the ping functionality by:

- Starting a temporary server via `e.startServer()`
- Executing the ping command through the test harness using `e.cmd(...).CombinedOutput()`
- Asserting that output contains "pong" for basic connectivity
- Verifying the final line indicates a direct path when testing the `--until-direct` flag

Run the specific test suite with:

```bash
$ go test ./cmd/tailcat -run TestPing
=== RUN   TestPing
--- PASS: TestPing (0.12s)
    --- PASS: TestPing/ping (0.06s)
    --- PASS: TestPing/until_direct (0.06s)
PASS
ok      github.com/tailscale/tailcat/cmd/tailcat   0.13s

```

## Summary

- The `tailcat ping` command tests Tailcat connectivity by sending **meow** discovery packets through the DERP network or direct paths.
- Successful responses display latency and the specific endpoint (DERP relay ID or direct node address) that answered the ping.
- Use `--until-direct` to verify that NAT traversal succeeds and direct connectivity is achievable.
- The repository's [`ping_test.go`](https://github.com/tailscale/tailcat/blob/main/ping_test.go) provides automated validation using the `newTestEnv` infrastructure.

## Frequently Asked Questions

### What does "via DERP(2)" mean in the ping output?

This indicates the ping traversed a DERP (Designated Encrypted Relay for Packets) relay server with region ID 2. According to the implementation in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go), this occurs when direct UDP connectivity cannot be established between nodes, forcing traffic through a relay node to ensure connectivity across restrictive NATs or firewalls.

### How can I confirm that direct connectivity is working?

Run `tailcat ping --until-direct <addrblob>`. The command will loop until the output shows a specific IP address and port (e.g., `via 10.0.0.2:12345`) rather than a DERP identifier. The `--timeout` flag limits how long the client attempts to establish the direct path before exiting.

### What is the difference between `tailcat ping` and standard ICMP ping?

While ICMP ping tests basic IP reachability using echo requests, `tailcat ping` specifically tests the Tailcat overlay network. It validates the discovery mechanism (`Client.DiscoPing`), encryption handshake readiness, and the specific network path (direct or relayed) that Tailcat traffic will actually use between nodes.

### Can I use tailcat ping without starting a server manually?

Yes. The repository's test suite in [`cmd/tailcat/ping_test.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/ping_test.go) demonstrates automated testing where `e.startServer()` programmatically launches a temporary server within the test context. For manual testing outside the test suite, you must have a running Tailcat server to generate the address blob required as the ping target.