mcping is a headless Minecraft Java latency checker. Each probe opens a real TCP connection, collects ICMP echo latency for the same resolved/connected IP, and speaks the Minecraft Java status protocol, which makes the result closer to what a player, proxy, or monitoring system experiences when reaching a server. Optional probes can also collect best-effort login/play latency. Route mode runs a standalone Minecraft TCP route trace through nexttrace.
Probe path:
SRV lookup -> A/AAAA lookup -> TCP connect -> Minecraft handshake/status -> Minecraft ping/pong -> ICMP echo to the same IP
optional: login/play probe
route mode: SRV/default/explicit port resolution -> nexttrace TCP route trace to the Minecraft port
Each probe prints realtime segmented timings. The final summary reports min / avg / max / median / p95 for every metric.
- Minecraft Java status/ping protocol probing
- ICMP echo probing through the system
pingcommand - Best-effort Minecraft login/play latency probing
- Minecraft handshake domain override for IP/proxy targets
- Standalone
nexttraceroute detection using TCP to the Minecraft port _minecraft._tcpSRV lookup support- Domain, IPv4, IPv6,
host:port, andhost porttarget formats - CLI style inspired by
pingandtcping - Continuous probing with
Ctrl+Csummary - IPv4-only and IPv6-only modes
- JSON output for monitoring integrations
- Cross-platform release build matrix
- Static Go binary with no third-party dependencies
Usage:
mcping [options] host [port]
Target:
host Server domain, IPv4, or IPv6
port Optional port. If omitted, SRV is tried first, then 25565.
Count:
-n count Number of probes, tcping-style
-c count Number of probes, ping-style; 0 means infinite
-t Probe until stopped
Timing:
-i seconds Interval between probes
-w ms Timeout per probe in milliseconds
--timeout seconds Timeout per probe in seconds; overrides -w
Network:
-4 IPv4 only
-6 IPv6 only
--no-srv Disable _minecraft._tcp SRV lookup
Minecraft:
--protocol n Minecraft protocol version used in the handshake, default 765
--play Also attempt a login/play latency probe
--play-name name Username for --play probes, default mcping
--domain name Override Minecraft handshake serverAddress/domain
--server-address name Same as --domain
Route:
--route Run only nexttrace TCP route detection to the Minecraft port
--route-timeout sec Timeout for --route, default 60
MCPING_NEXTTRACE nexttrace executable path, fallback when PATH lookup fails
Output:
--json Print JSON
--version Print version information
Realtime output example:
Target: mc.hypixel.net -> mc.hypixel.net:25565 (default-port, serverAddress=mc.hypixel.net)
2026-06-26 03:22:47.891 #001 ip=mc.hypixel.net:25565(172.65.197.160:25565) icmp=203.00 ms tcp=205.31 ms status=358.43 ms pong=270.49 ms play=fail(online-mode encryption requested; authenticated/encrypted play probing is not supported)
Field meanings:
Target Final target used for probing
serverAddress Address sent inside the Minecraft handshake; can be overridden with --domain
ip Display target and actual remote address as host:port(ip:port)
icmp ICMP echo latency to the same IP used by this probe
tcp TCP connect time
status Minecraft handshake + status request/response time
pong Minecraft ping/pong round-trip time
play Best-effort login/play latency, only with --play
status, pong, and play:
status = Minecraft handshake + status request/response phase
pong = Minecraft ping/pong RTT after status has completed
play = login/play probe time until login success when the server allows it
--play is intentionally conservative. Online-mode servers request encrypted authenticated login, which this tool does not perform. In that case the status/pong metrics can still succeed, while play reports a failure reason.
Some Minecraft servers and proxies check the hostname inside the Minecraft handshake. If you connect directly to an IP address, the TCP connection can succeed while the server rejects or misroutes the Minecraft protocol because it expected a domain.
Use --domain to connect to one host/IP while sending a different Minecraft serverAddress:
./mcping-linux-amd64-v1 203.0.113.10 --domain play.example.com
./mcping-linux-amd64-v1 203.0.113.10 25565 --domain play.example.com--server-address is an alias for --domain.
When no explicit port is provided, --domain also supports Minecraft SRV lookup. In that case _minecraft._tcp.<domain> can provide the Minecraft port, while the TCP connection host remains the target you typed:
./mcping-linux-amd64-v1 203.0.113.10 --domain play.example.comIf play.example.com has an SRV record pointing to port 25566, mcping connects to 203.0.113.10:25566 and sends play.example.com in the Minecraft handshake.
Explicit ports still skip SRV:
./mcping-linux-amd64-v1 203.0.113.10 25565 --domain play.example.comThis affects Minecraft status/pong and --play handshakes. It does not change the TCP connection host, ICMP target, or --route target. It can change the port when --domain has an SRV record and no explicit port was supplied.
--route is route-only mode. It does not run ICMP ping, TCP latency probes, Minecraft status, Minecraft pong, or play probing. It resolves the Minecraft target and then runs nexttrace once:
./mcping-linux-amd64-v1 mc.example.net --routeThe route trace is Minecraft-aware in target selection:
SRV/default/explicit port resolution -> first resolved A/AAAA candidate -> nexttrace --tcp --port <minecraft-port>
This means the route trace follows the TCP path to the Minecraft service port instead of a generic ICMP traceroute. For Cloudflare Anycast and other proxy/edge deployments, the traced destination is the player-facing edge IP selected by normal DNS/SRV resolution, not the hidden origin.
Important limits:
nexttrace traces the network path with TCP packets to the Minecraft port.
It cannot make every intermediate router answer a Minecraft status/pong packet.
Use normal mcping output for tcp/status/pong latency, and use --route separately for path visibility.
nexttrace is not bundled into mcping. Route lookup order is:
nexttrace in system PATH -> MCPING_NEXTTRACE environment variable -> install command
Point mcping to a custom nexttrace executable with an environment variable:
$env:MCPING_NEXTTRACE="C:\Tools\nexttrace.exe"
.\mcping-windows-amd64-v1.exe mc.example.net --routeIf nexttrace is not in system PATH and MCPING_NEXTTRACE is not set, --route prints the official install command:
curl -sL nxtrace.org/nt | bashOn Linux, TCP route tracing can still require raw socket permissions because traceroute receives ICMP TTL-exceeded replies while sending TCP probes. If nexttrace reports operation not permitted, grant the executable the required capabilities:
sudo setcap cap_net_raw,cap_net_admin+eip "$(readlink -f "$(command -v nexttrace)")"
getcap "$(readlink -f "$(command -v nexttrace)")"On Windows, TCP route tracing with nexttrace may require Administrator privileges because raw packet capture/injection is commonly needed.
Final summary example:
Summary: sent=2 received=2 lost=0 loss=0.0%
ICMP: min=200.00 ms avg=201.50 ms max=203.00 ms median=201.50 ms p95=202.85 ms
TCP: min=202.42 ms avg=203.87 ms max=205.31 ms median=203.87 ms p95=205.17 ms
Status: min=358.43 ms avg=363.09 ms max=367.75 ms median=363.09 ms p95=367.29 ms
Pong: min=261.90 ms avg=266.20 ms max=270.49 ms median=266.20 ms p95=270.06 ms
Play: min=421.33 ms avg=424.10 ms max=426.87 ms median=424.10 ms p95=426.59 ms
Summary fields:
sent Number of probes started
received Number of successful pong responses
lost Number of failed probes
loss Failure percentage
min Minimum value
avg Average value
max Maximum value
median Median value
p95 95th percentile; 95% of successful probes are <= this value
p95 is useful for understanding stability. Averages can look fine while rare spikes are still bad; p95 makes those tail-latency problems easier to see.
Normal probe example:
{
"target": {
"original_host": "mc.hypixel.net",
"connect_host": "mc.hypixel.net",
"port": 25565,
"server_address": "mc.hypixel.net",
"source": "default-port"
},
"samples": [
{
"timestamp": "2026-06-26 03:22:50.047",
"ok": true,
"icmp_ms": 203.000,
"connect_ms": 208.523,
"status_ms": 381.426,
"pong_ms": 267.408,
"play_ms": null,
"ip": "172.65.197.160",
"address": "172.65.197.160:25565",
"error": null,
"play_error": "online-mode encryption requested; authenticated/encrypted play probing is not supported"
}
],
"summary": {
"sent": 1,
"received": 1,
"lost": 0,
"loss_percent": 0,
"icmp": {
"min_ms": 203.000,
"avg_ms": 203.000,
"max_ms": 203.000,
"median_ms": 203.000,
"p95_ms": 203.000
},
"tcp": {
"min_ms": 208.523,
"avg_ms": 208.523,
"max_ms": 208.523,
"median_ms": 208.523,
"p95_ms": 208.523
},
"status": {
"min_ms": 381.426,
"avg_ms": 381.426,
"max_ms": 381.426,
"median_ms": 381.426,
"p95_ms": 381.426
},
"pong": {
"min_ms": 267.408,
"avg_ms": 267.408,
"max_ms": 267.408,
"median_ms": 267.408,
"p95_ms": 267.408
}
}
}Route-only example:
{
"target": {
"original_host": "mc.hypixel.net",
"connect_host": "mc.hypixel.net",
"port": 25565,
"server_address": "mc.hypixel.net",
"source": "default-port"
},
"samples": [],
"summary": {
"sent": 0,
"received": 0,
"lost": 0,
"loss_percent": 0
},
"route": {
"tool": "nexttrace",
"protocol": "minecraft_tcp",
"target": "172.65.197.160",
"port": 25565,
"address": "172.65.197.160:25565",
"command": ["nexttrace", "--tcp", "--port", "25565", "--json", "172.65.197.160"],
"ok": true,
"duration_ms": 12034.120,
"output": "{...nexttrace json output...}"
}
}The JSON summary includes grouped stats for icmp, tcp, status, pong, and play when samples exist for those metrics. Route-only JSON contains an empty samples array, a zeroed summary object, and a route object with the nexttrace command, selected target, duration, raw output, and any error or exit code.
When no explicit port is provided, mcping tries:
_minecraft._tcp.<host>
If an SRV record exists:
connect address = SRV target and port
serverAddress = original host provided by the user
If no SRV record exists, it falls back to:
host:25565
Explicit ports skip SRV lookup:
./mcping-linux-amd64-v1 mc.example.net 25566
./mcping-linux-amd64-v1 mc.example.net:25566Disable SRV lookup:
./mcping-linux-amd64-v1 mc.example.net --no-srv0 At least one probe succeeded
1 All probes failed
2 Invalid arguments or target resolution failed
Highlights:
- Added
--domain/--server-addressto override the Minecraft handshakeserverAddressfor IP and proxy targets. - Domain override works with status, pong, and optional play probes.
- Domain override supports Minecraft SRV lookup when no explicit port is provided, using the SRV port while keeping the typed connection host.
- Explicit ports still skip SRV lookup.
- Invalid SRV ports are rejected during target resolution.
MCPING_NEXTTRACEdocumentation now correctly describes it as an executable path fallback after systemPATHlookup.
Build all supported release targets:
powershell -ExecutionPolicy Bypass -File .\scripts\build.ps1 -Version v0.5.0The build script first runs:
go test -buildvcs=false ./...Then it writes release binaries into:
dist/
It also writes SHA256 checksums to:
dist/checksums.txt
Manual single-target build:
$env:CGO_ENABLED="0"
$env:GOOS="linux"
$env:GOARCH="amd64"
$env:GOAMD64="v1"
go build -buildvcs=false -trimpath -ldflags "-s -w" -o dist/mcping-linux-amd64-v1 ./cmd/mcping.
|-- cmd/mcping/ CLI source code and tests
|-- dist/ Release binaries and checksums
|-- scripts/ Build scripts
|-- go.mod Go module definition
|-- LICENSE MIT license
`-- README.md Project documentation
| Platform | Architecture | Variant | File | Description |
|---|---|---|---|---|
| Android | ARM64 | - | mcping-android-arm64 |
Android ARM64 |
| macOS | AMD64 | V1 | mcping-darwin-amd64-v1 |
Compatible AMD64 build |
| macOS | AMD64 | V3 | mcping-darwin-amd64-v3 |
Modern AMD64 optimized build |
| macOS | ARM64 | - | mcping-darwin-arm64 |
Apple Silicon |
| FreeBSD | 386 | V1 | mcping-freebsd-386-v1 |
FreeBSD 32-bit |
| FreeBSD | AMD64 | V1 | mcping-freebsd-amd64-v1 |
FreeBSD AMD64 V1 |
| FreeBSD | AMD64 | V3 | mcping-freebsd-amd64-v3 |
FreeBSD AMD64 V3 |
| FreeBSD | ARM64 | - | mcping-freebsd-arm64 |
FreeBSD ARM64 |
| Linux | 386 | V1 | mcping-linux-386-v1 |
Linux 32-bit |
| Linux | AMD64 | V1 | mcping-linux-amd64-v1 |
Compatible AMD64 build |
| Linux | AMD64 | V3 | mcping-linux-amd64-v3 |
Modern AMD64 optimized build |
| Linux | ARM | V5 | mcping-linux-arm-5 |
Linux ARM v5 |
| Linux | ARM | V6 | mcping-linux-arm-6 |
Linux ARM v6 |
| Linux | ARM | V7 | mcping-linux-arm-7 |
Linux ARM v7 |
| Linux | ARM64 | - | mcping-linux-arm64 |
Linux ARM64 |
| Linux | LoongArch64 | - | mcping-linux-loong64 |
Linux LoongArch64 |
| Linux | MIPS | - | mcping-linux-mips |
Linux MIPS |
| Linux | MIPS64 | - | mcping-linux-mips64 |
Linux MIPS64 |
| Linux | MIPS64LE | - | mcping-linux-mips64le |
Linux MIPS64 little-endian |
| Linux | MIPSLE | - | mcping-linux-mipsle |
Linux MIPS little-endian |
| Linux | RISC-V64 | - | mcping-linux-riscv64 |
Linux RISC-V 64-bit |
| Linux | S390X | - | mcping-linux-s390x |
Linux IBM Z |
| Windows | 386 | V1 | mcping-windows-386-v1.exe |
Windows 32-bit |
| Windows | AMD64 | V1 | mcping-windows-amd64-v1.exe |
Compatible AMD64 build |
| Windows | AMD64 | V3 | mcping-windows-amd64-v3.exe |
Modern AMD64 optimized build |
| Windows | ARM64 | - | mcping-windows-arm64.exe |
Windows ARM64 |
windows/arm is not supported by the current standard Go toolchain, so mcping-windows-arm-7.exe is not generated.
scripts/build.ps1 generates a plain SHA256 checksum file:
dist/checksums.txt
Format:
<sha256> <filename>
Example verification on Linux:
cd dist
sha256sum -c checksums.txtV1 Baseline AMD64 instruction set. Best compatibility.
V3 Newer AMD64 instruction set. Potentially faster, but less compatible.
If unsure, choose V1.
go test -buildvcs=false ./...Covered areas:
target parsing
ping/tcping-style argument parsing
VarInt encoding/decoding
IPv4/IPv6 filtering
ICMP ping output parsing
nexttrace route argument building
summary statistics
MIT. See LICENSE.
System ping usually uses ICMP. Minecraft Java clients use TCP and the Minecraft protocol. A server, proxy, or firewall may block ICMP while TCP 25565 works, or ICMP may be fast while Minecraft status is slow. mcping reports both ICMP and Minecraft protocol timings so you can compare the layers.
icmp runs the operating system ping command once per probe and parses its time=... ms result. When TCP connects successfully, ICMP is sent to the same remote IP used by that TCP connection after the Minecraft protocol timings have been collected. If TCP cannot connect, ICMP is sent to the first resolved candidate IP. ICMP may be blocked or deprioritized independently from TCP 25565.
When a server uses Cloudflare Anycast or another TCP proxy, mcping measures the player-facing edge/proxy path, not the hidden origin behind it. This is usually the correct latency from the player's point of view.
To avoid measuring a different Anycast edge, ICMP is aligned to the same IP used by the probe's TCP connection. ICMP is collected after the Minecraft protocol timings, so an ICMP timeout does not inflate status or pong. Still, ICMP and TCP/Minecraft traffic can be handled differently by Cloudflare, so use tcp, status, and especially pong as the authoritative Minecraft latency metrics. Treat icmp as a comparison signal.
When --route is enabled, route detection is standalone. It resolves the Minecraft target, selects the first resolved A/AAAA candidate allowed by -4 or -6, and runs a TCP trace to the Minecraft port. This is the closest route-level view of the path a Minecraft client uses, but it still cannot reveal a hidden origin behind Cloudflare or another proxy.
--play opens a separate Minecraft login connection and measures how long it takes to reach login success when the server allows an unauthenticated best-effort probe. Online-mode servers request encrypted authenticated login; when that happens, play reports an error instead of pretending to measure gameplay latency.
play is closer to player entry behavior than server-list pong, but it is not a full replacement for a real authenticated client session with Play-state keepalive handling.
This follows common Minecraft client behavior. If a port is provided, the tool connects to that exact host and port instead of querying _minecraft._tcp.