iceFetch reads the ICE candidates a Minecraft Bedrock server advertises over NetherNet — the WebRTC-based transport that replaced RakNet. It does this purely at the signaling layer, from a Cloudflare Worker.
Modern Minecraft Bedrock Dedicated Server (BDS) can run with transport=nethernet instead of the classic RakNet UDP protocol. NetherNet is built on WebRTC: the actual game data flows over an encrypted SCTP-over-DTLS data channel, and connections are negotiated with SDP offers/answers and ICE candidates, exactly like a browser peer connection.
The negotiation (signaling) happens over a small HTTP server that BDS opens on its TCP port (e.g. 19132). A client discovers the server, then performs one HTTP request to exchange session descriptions.
GET /v1/join → { name, protocol, version, players, maxPlayers, … }
POST /v1/join/{networkId} → an SDP answer (Content-Type: application/sdp)An ICE candidate is one possible network address a peer can be reached at — an IP, a port, and a type (host for a local/interface address, srflx for a NAT-reflexive public address, relay for a TURN relay). During negotiation each side lists its candidates in the SDP; the two peers then probe the pairs to find a route that works.
When you send an offer to a NetherNet server, its SDP answer contains the candidates the server is reachable at — the real UDP endpoints its game traffic uses. That is what iceFetch extracts and shows you.
a=identity SDP attribute) backed by a real Microsoft/Xbox account, because BDS rejects offers without one.POST /v1/join/{networkId} over a raw TCP (or TLS) connection from a Cloudflare Worker.A Cloudflare Worker has no UDP, no DTLS, and no WebRTC stack. iceFetch can complete the signaling handshake, but never the media handshake — so it can read a server's candidates, but it can never open a game session. It is a diagnostic / reconnaissance tool, not a client.
| Endpoint | What it returns |
|---|---|
GET /api/info?host=&port= | the server's /v1/join metadata |
POST /api/offer | { candidates[], answer, iceUfrag, … } |
curl -X POST https://icefetch.tools.kt04.com/api/offer \
-H 'content-type: application/json' \
-d '{"host":"play.example.net","port":19132}'
Body fields: host (required), port (default 19132), networkId (optional decimal uint64), tls (auto-detected — set true/false to force), fresh (bypass cache).
Only on servers running NetherNet (BDS 1.21.60+ with transport=nethernet, or networks that front their servers with it). Pure RakNet (UDP-only) servers have no HTTP signaling endpoint to query.
A 200 response with an empty candidate list means the server's UDP port pool is currently exhausted — too many pending signaling sessions. It recovers after those sessions time out.
The candidates are the endpoints the server itself advertises for gameplay. For large networks these are often the backend game-node IPs behind a proxied hostname.
ToolLearnArticlesPrivacyTerms · iceFetch is not affiliated with Mojang or Microsoft.