Table of Contents

Concepts and terminology

Endpoint, endpoint ID, ALPN, transport address, relay, path, discovery, ticket — the vocabulary go-iroh uses.

These are the terms the rest of the site assumes. Where a term belongs to the iroh protocol rather than to Go, this page gives the Go spelling and links upstream for the protocol definition.

Endpoint

An endpoint is “a bound iroh node: it owns a secret key, a UDP socket, and the QUIC transport used to dial and accept connections” (iroh.Endpoint’s doc comment). It is created with iroh.Bind and closed with Endpoint.Shutdown — there is no Close method and no NewEndpoint constructor.

An Endpoint is safe for concurrent use.

Endpoint ID

The public half of the endpoint’s ed25519 key, spelled key.EndpointID. It is the peer’s name: everything else about an address is just a hint about how to reach it.

Two textual forms appear in the tooling: 64 hex characters, and the z-base-32 form produced by EndpointID.Z32(). The iroh command converts between them.

Upstream Rust iroh calls this a NodeId and its address a NodeAddr. go-iroh uses EndpointID and EndpointAddr. The wire encoding is the same; the Go names are not aliases of the Rust ones. This is the single most common source of confusion when reading upstream docs alongside Go code.

Transport address and endpoint address

A netaddr.TransportAddr is one way to reach a peer. Three kinds ship:

Kind Go type String form
Direct IP netaddr.IPAddr ip:127.0.0.1:4433
Relay netaddr.RelayAddr relay:https://use1-1.relay.iroh.network./
Custom transport netaddr.CustomAddr custom:…

A netaddr.EndpointAddr combines an endpoint ID with zero or more transport addresses. Its doc comment states the rule: “To establish a connection both the key.EndpointID and at least one path (a relay URL or a direct IP address) are needed; an EndpointAddr with no addresses is still usable together with an address-lookup service.”

Build one with netaddr.NewEndpointAddr(id) and the WithIP, WithRelayURL, and WithAddrs builders.

ALPN

ALPN is Application-Layer Protocol Negotiation, the TLS extension that lets peers agree which application protocol a QUIC connection carries. go-iroh routes incoming connections to handlers by ALPN.

The Go API takes ALPN values as strings — TLS ALPN values are byte strings on the wire, and Go strings preserve arbitrary bytes while keeping the common printable-ASCII case simple. Protocol ALPNs in the ecosystem look like /iroh-gossip/1 or n0/tracker/1; pick a namespaced value for your own.

Path

A path is a concrete network route in use by a connection: a direct UDP path between two addresses, or a path through a relay. Conn.Paths() returns the current set and Conn.WatchPaths observes changes. go-iroh’s QUIC layer supports multipath, so a connection can hold more than one at a time and migrate between them — typically starting on a relay path and upgrading to a direct path once hole punching succeeds.

Relay

A relay is a public server that forwards packets between endpoints that cannot yet (or ever) reach each other directly, and helps them discover their own observed addresses. The relay package holds the public configuration types — relay URLs grouped into a Map, per-relay Config, and a Mode selecting which relays an endpoint uses. The client and wire protocol are internal.

See Relays and discovery, and upstream’s relay documentation for the protocol.

Discovery / address lookup

Given only an endpoint ID, an address-lookup service answers “where is this peer?”. go-iroh calls the abstraction AddressLookupServices in the iroh package, with pluggable AddressPublisher and AddressResolver halves. Shipped backends: DNS, pkarr (signed DNS records published to a relay), static, in-memory, and mDNS for local networks.

Ticket

A ticket is the compact string form of an address for out-of-band sharing. An endpoint ticket “starts with endpoint followed by lowercase base32 without padding” (endpointticket package doc). The blobs package defines the corresponding blob tickets.

Wire compatibility

go-iroh’s stated goal is wire compatibility with Rust iroh: the same QUIC, TLS, relay, and protocol bytes, not a shared codebase. The README describes the module as “a clean-room Go port targeting wire compatibility with upstream Rust iroh. It is not affiliated with the n0 team.”

What is mechanically proven, and by which test gate, is covered in Testing and interop.

Next steps

Last updated: 2026-08-20