Changelog
July 29, 2026 · View on GitHub
All notable changes to this project will be documented in this file.
Note:
- The format is based on Keep a Changelog.
- This project adheres to Semantic Versioning.
Legend
The following emojis are used to highlight certain changes:
- 🛠 - BREAKING CHANGE. Action is required if you use this functionality.
- ✨ - Noteworthy change to be aware of.
[Unreleased]
Added
Changed
Removed
Fixed
Security
[v0.16.0] - 2026-07-29
Added
- someguy now replaces a
/dnsaddrprovider address with the addresses it names, before it appliesfilter-addrs. A/dnsaddrcarries no transport component, so a filter could neither match nor exclude it: a provider reachable only through a/dnsaddrwas dropped from a filtered response, and a provider the client asked to exclude survived one. someguy resolves on every request by default. A request that sendsfilter-addrsgets the/dnsaddrreplaced, since keeping it would let a record survive a filter meant to exclude it (unless a positive filter entry namesdnsaddr, the one filter that can match it; then the/dnsaddris kept). A request without a filter gets the resolved addresses added and keeps the/dnsaddr, so it can dial straight away and still re-resolve later. SetSOMEGUY_DNSADDR_RESOLUTION=replaceto drop the/dnsaddrfrom unfiltered responses too,filteredto skip the lookup for unfiltered requests, orneverto disable it (the default isappend). Lookups are cached and bounded per request, watched by two new metrics:someguy_routers_dnsaddr_resolutionsandsomeguy_routers_dnsaddr_resolution_duration_seconds. Seedocs/dnsaddr-resolution.md. #174 - Addresses within a record are now ordered by how directly a client can dial them: IP first, then DNS names, then
/dnsaddr, with/p2p-circuitrelays last. #174
Changed
- boxo v0.42.1 and go-libp2p v0.49.0
- Go 1.26 is now the minimum. #174
[v0.15.0] - 2026-07-27
Added
- Background
FindPeerlookups, the ones someguy dispatches for provider records that arrive without addresses, are now capped at 512 concurrent per instance. These lookups outlive the request that triggered them, so a client could close its connection and leave a full DHT walk running, with nothing bounding how many piled up. Measured ondelegated-ipfs.devan instance runs on the order of 20 at once, so the cap only engages far outside normal traffic. Three metrics were added to watch it:someguy_cached_router_find_peer_lookups_in_flight,someguy_cached_router_find_peer_lookups_rejected, andsomeguy_cached_router_find_peer_lookup_duration_seconds. Tune withSOMEGUY_CACHED_ADDR_BOOK_MAX_CONCURRENT_FIND_PEERS. #169 SOMEGUY_ROUTING_TIMEOUTsets how long one/routing/v1request may spend in the routers, defaulting to 25s. It has to stay below the timeout clients put on the whole request, otherwise a client gives up before someguy flushes and every record someguy resolved is lost. #169
Changed
- boxo (
main, past v0.42.0) and go-libp2p-kad-dht v0.42.1 #171 - someguy now shuts the DHT down explicitly. Its constructors stopped taking a context in go-libp2p-kad-dht v0.42.0, so cancelling the context that built them no longer stops their long-lived goroutines.
SIGTERMnow closes both the standard and accelerated clients before someguy exits. #171 /routing/v1responses no longer let a cache serve a two-day-old answer while someguy is healthy.stale-while-revalidateis now 10 minutes for responses with results and 1 minute for empty ones, which covers a background refresh.stale-if-erroronly applies when someguy is failing, so responses with results keep the 48h Amino DHT expiration window, and empty ones drop to 1 hour.max-ageis unchanged. The addresses someguy returns come from short-lived sources such as relay reservations, so a stale window measured in days handed clients addresses that had stopped working long ago. ipfs/boxo#1195
Fixed
Accept: application/x-ndjsonresponses now reach the client as each record is produced, instead of arriving in one batch at the end. Response compression was holding writes back until 200 bytes had accumulated, and a provider record is often smaller than that, so a provider someguy had already resolved sat in a buffer while it looked up the rest. Clients that give up before someguy finishes, such as Helia's delegated routing client with its 30s deadline, saw an empty result even though providers had been found. Response headers were withheld the same way, so the request appeared to hang. #169- someguy now stops its routing lookups at 25s rather than 30s, so it finishes and flushes before clients that bound the whole request at 30s walk away. Results found near the deadline now reach the client instead of being discarded with the aborted request. #169
[v0.14.1] - 2026-07-14
Fixed
- someguy now expires
/p2p-circuit(relay) addresses from its cache much sooner than direct ones. A relay reservation is short-lived: it lasts at most an hour and is dropped the moment the peer disconnects from the relay, so a relay address kept for the usual 48 hours is often long dead by the time a client dials it. Relay addresses now use a shorter TTL (twice the relay reservation TTL by default) and are renewed only while the peer stays reachable, so working relay paths survive and dead ones age out within hours instead of days. Seedocs/peer-address-caching.md. /routing/v1responses now list direct addresses before/p2p-circuit(relay) addresses. A client that dials addresses in order reaches a directly dialable one first and only falls back to a relay, which is slower and exists mainly to bootstrap a direct connection.
[v0.14.0] - 2026-06-08
Changed
Fixed
GetIPNSno longer returns an IPNS record whose EOL has already passed. An expired record is cryptographically invalid, so it is treated as not found, and when multiple routers answer the first non-expired record is returned. #154/routing/v1/ipns/{name}no longer gives a cache a freshness window that outlives the record. It capsmax-ageto the record's remaining validity and sizes thestale-while-revalidate/stale-if-errorwindow to fit within its EOL. An expired record, or one without an EOL validity, returnsCache-Control: no-store. #155/routing/v1/peers/{peerid}now serves addresses cache-first, the same way/routing/v1/providers/{cid}does. It answers from the cached address book and host peerstore before falling back to a DHT lookup, so a relay-dependent peer that is absent from peer routing but recently seen as a provider is no longer answered with an empty result. Seedocs/peer-address-caching.md. #153- A completed identify now prunes a peer's cached addresses down to its current advertised set (signed peer record or identify listen addresses) plus any live-connection address, instead of unioning forever. This stops stale certhashes, dead relay circuits, and rotated NAT ports from accumulating across provider lookups and gossip. #153
- Multiaddrs in
/routing/v1responses are returned in a stable sorted order. They previously came back in nondeterministic order, so repeated requests for the same peer or provider returned the same addresses shuffled differently. #153
Security
- The OpenTelemetry OTLP HTTP exporter now caps response bodies at 4 MiB, so a hostile or man-in-the-middle collector cannot exhaust someguy's memory (CVE-2026-39882). The gRPC exporter was never affected. #155
[v0.13.0] - 2026-05-26
Added
--records-limit/SOMEGUY_RECORDS_LIMIT(default100) caps results forAccept: application/json, matching the SHOULD-cap in HTTP Routing v1 §4.1.5. Set to0to disable the cap. #150--streaming-records-limit/SOMEGUY_STREAMING_RECORDS_LIMIT(default1000) caps results forAccept: application/x-ndjson. Set to0to disable the cap. #150
Changed
- ✨ JSON responses return up to 100 providers (previously 20). NDJSON streams up to 1000 results (previously unbounded). Both caps are tunable via the new flags. #150
- boxo v0.40.0
- go-libp2p-kad-dht v0.40.0
- go-log/v2 v2.9.2
Fixed
- JSON delegated routing requests now surface close to the requested number of providers. The boxo server enforces the records limit after filtering, so records without addresses no longer shrink the response below
--records-limit. #150
[v0.12.0] - 2026-04-24
Changed
- boxo v0.39.0
- go-libp2p v0.48.0
- go-libp2p-kad-dht v0.39.1
- bumped Docker workflow actions (
setup-qemu-action,setup-buildx-action,login-action,build-push-action) to latest majors - Docker image builder bumped to
golang:1.26-bookworm - clearer
--helpdescriptions forsomeguy,someguy start, andsomeguy ask(including per-subcommand short descriptions and correctUSAGElines) - README,
docs/environment-variables.md,docs/metrics.md, anddocs/tracing.mdrewritten for clarity (active voice, removed duplicated wording)
Fixed
docs/environment-variables.md: replaced the self-referential default forSOMEGUY_LIBP2P_LISTEN_ADDRSwith a pointer tosomeguy start --helpso the docs cannot drift from the CLI defaultdocs/metrics.md: fixed "Prometheus Glient" typo, corrected plural/subject-verb agreement, and documented the previously-undocumentedsomeguy_cached_addr_book_probed_peerscounterdocs/tracing.md: corrected the example port (8090→8190, matchingSOMEGUY_LISTEN_ADDRESSdefault), replaced brokenheaders.mdlinks with inline descriptions, and clarified that tracing covers inbound HTTP routing requests (not "gateway" requests)
[v0.11.1]
Changed
[v0.11.0] - 2025-11-20
Added
- Added support for IPIP-476:
/routing/v1/peers/closest/{key}endpoint for finding DHT-closest peers (#124, #127)- Returns DHT-closest peers to a given CID or PeerID
- Accepts both CID and legacy PeerID formats (e.g.,
12D3KooW...) - Uses WAN DHT only for more reliable results
- Includes cached addresses in results when available
- Properly returns HTTP 500 when DHT is disabled
- AutoConf support: automatic configuration of bootstrap peers and delegated routing endpoints (#123). When enabled (default), the
autoplaceholder is replaced with network-recommended values.- All endpoint flags (
--provider-endpoints,--peer-endpoints,--ipns-endpoints) default toauto - See environment-variables.md for configuration details
- All endpoint flags (
Changed
Removed
Fixed
- Fixed multiple race conditions and deadlocks in iterator implementations (#119)
Security
[v0.10.0]
Added
- Automatic generation of peer IDs for HTTP block providers when not explicitly configured (#117)
- When
SOMEGUY_HTTP_BLOCK_PROVIDER_ENDPOINTSare configured but noSOMEGUY_HTTP_BLOCK_PROVIDER_PEERIDSare configured, synthetic PeerIDs will now be autogenerated. These are deterministic placeholders derived from endpoint URLs, used only for routing system compatibility with HTTP-based trustless gateways - no libp2p cryptographic operations are performed with these IDs
- When
Changed
[v0.9.1]
Added
- Added exporting of routing http client metrics: the endpoint will now include
someguy_routing_http_client_*metrics when delegated routing clients are used:- Histogram: the latency of operations by the routing HTTP client
someguy_routing_http_client_latency_bucket{code,error,host,operation,le}someguy_routing_http_client_latency_sum{code,error,host,operation}someguy_routing_http_client_latency_count{code,error,host,operation}
- Histogram: the number of elements in a response collection
someguy_routing_http_client_length_bucket{host,operation,le}someguy_routing_http_client_length_sum{host,operation}someguy_routing_http_client_length_count{host,operation}
- See docs/metrics.md for more details.
- Histogram: the latency of operations by the routing HTTP client
[v0.9.0]
Added
- Added
http-block-provider-endpointsandhttp-block-provider-peeridsoptions to enable using a trustless HTTP gateway as a source for synthetic content routing records.- When the configured gateway responds with HTTP 200 to an HTTP HEAD request for a block (
HEAD /ipfs/{cid}?format=raw),FindProvidersreturns a provider record containing a predefined PeerID and the HTTP gateway as a multiaddr with/tls/httpsuffix.
- When the configured gateway responds with HTTP 200 to an HTTP HEAD request for a block (
Changed
accelerated-dhtoption was removed and replaced with adhtoption which enables toggling between the standard client, accelerated client and being disabled- boxo v0.30.0
- go-libp2p v0.41.1
- go-libp2p-kad-dht v0.32.0
Removed
Fixed
Security
[v0.8.1]
This release includes a number of dependency updates that include bug fixes and improvements.
Changed
[v0.8.0]
Added
- Enabled CORS for PUT requests to
/routing/v1/ipns.
[v0.7.1]
Fixed
- Fix a bug whereby, cached peers with private multiaddrs were returned in
/routing/v1/providersresponses, as they were not passing throughsanitizeRouter.
[v0.7.0]
Added
- Peer addresses are cached for 48h to match provider record expiration on Amino DHT.
- In the background, someguy probes cached peers at most once per hour (
PeerProbeThreshold) by attempting to dial them to keep their multiaddrs up to date. If a peer is not reachable, an exponential backoff is applied to reduce the frequency of probing. If a cached peer is unreachable for more than 48h (MaxBackoffDuration), it is removed from the cache. - Someguy now augments providers missing addresses in
FindProviderswith cached addresses. If a peer is encountered with no cached addresses,FindPeeris dispatched in the background and the result is streamed in the reponse. Providers for which no addresses can be found, are omitted from the response.- This can be enabled via
SOMEGUY_CACHED_ADDR_BOOK=true|false(enabled by default) - Two additional configuration options for the
cachedAddrBookimplementation:SOMEGUY_CACHED_ADDR_BOOK_ACTIVE_PROBINGwhether to actively probe cached peers in the background to keep their multiaddrs up to date.SOMEGUY_CACHED_ADDR_BOOK_RECENT_TTLto adjust the TTL for cached addresses of recently connected peers.
- This can be enabled via
[v0.6.0]
Added
- Add request tracing with sampling or require token for requests with Traceparent header. See tracing.md for more details.
Changed
- go-libp2p-kad-dht updated to v0.28.1
- Metrics
someguy_http_request_duration_secondsandsomeguy_http_response_size_byteswere replaced withdelegated_routing_server_http_request_duration_secondsanddelegated_routing_server_http_response_size_bytesfrom upstreamboxo/routing/http/server.
[v0.5.3]
Fixed
- default config: restore proxying of all results from IPNI at
cid.contact#83
[v0.5.2]
Changed
[v0.5.0]
Added
- Added support for IPIP-484 which allows filtering network transports (addresses) and transfer protocols (bitswap, etc) in
/routing/v1/responses. #82
Changed
[v0.4.2]
Fixed
- go-libp2p-kad-dht v0.26.1 fixes a bug where
FindPeerdid not return results for peers behind NAT which only have p2p-circuit multiaddrs. #80
[v0.4.1]
Added
SOMEGUY_LIBP2P_LISTEN_ADDRSconfig environment variable for customizing the interfaces, ports, and transports of the libp2p host created by someguy. #79
Fixed
- enabled NAT port map and Hole Punching to increase connectivity in non-public network topologies #79
[v0.4.0]
Changed
Fixed
- libp2p identify agentVersion correctly indicates someguy version
[v0.3.0]
Changed
- boxo 0.21
routing/httpfixes (release notes) - go-libp2p 0.35
Fixed
--versionnow includes the release tagstartcommand supports a graceful shutdown and improved handling of interrupt signals
[v0.2.3]
Changed
- The resource manager's defaults have been improved based on Rainbow's and Kubo's defaults. In addition, you can now customize a few options using flags, or environment variables.
[v0.2.2]
Fixed
- The
/routing/v1/peersendpoint correctly filters out private addresses.
[v0.2.1]
Fixed
- Upgraded Boxo with fix to ensure that
/routing/v1/peersendpoint accepts all variants of Peer IDs that are seen in the wild.