IPIP-351: IPNS Signed Records Response Format on HTTP Gateways will return a raw IPNS record, allowing a custom light client to verify IPNS without having to run DHT client.
Users asked for the ability to export both CIDs and IPNS record into a CAR, transport over sneakernet and load this on airgapped node, which is a good use case.
Another use case is Decentralized Gateway WG, which could benefit from the ability to have a single round-trip that includes full or partial CAR with content + ipns-record.
Broad strokes UX we want to accommodate:
$ curl http://gateway.foo/ipns/{id}?format=car&something > ipns-site-dump.car
$ ipfs import ipns-site-dump.car # imaginary command that goes beyond DAGs
$ ipfs resolve /ipns/{id} # works, even in offline mode
$ ipfs dag stat /ipns/{id} # works, even in offline mode
Initial notes / subtasks
Status as of 2026Q3
Nobody is working on this. Summary of what exists and what is missing, so it can be picked up.
Trustless two-step retrieval works today, over plain HTTP:
GET /ipns/{name}?format=ipns-record (IPIP-351): the client verifies the signature and resolves the record to /ipfs/{cid}, or stops on mismatch.
GET /ipfs/{cid}?format=car with dag-scope, entity-bytes and order=dfs (IPIP-402): the client verifies each block as it arrives and drops the connection on the first block that fails its hash or is not expected in the DAG.
What is missing is the single round trip. GET /ipns/{name}?format=car today returns the CAR of the resolved content without the record, so the client cannot verify the IPNS step from that response alone. The smallest useful shape: a CAR with the ipns-record block (codec 0x0300) first, then the IPIP-402 stream from the root the record points at. The client checks the record before hashing anything else and can drop the connection after the first bad block. Plain HTTP, no new protocol or transport needed.
Open questions, unchanged from the list above:
- CAR roots: only the record, only the data root, or both.
- Request signal: an explicit
format value or a CAR content-type parameter (IPIP-412 style), so a client can tell a record-first CAR from a plain one served by an older gateway.
Kubo side: no content-path import/export exists, and ipfs dag import does not know the ipns-record codec.
IPIP-351: IPNS Signed Records Response Format on HTTP Gateways will return a raw IPNS record, allowing a custom light client to verify IPNS without having to run DHT client.
Users asked for the ability to export both CIDs and IPNS record into a CAR, transport over sneakernet and load this on airgapped node, which is a good use case.
Another use case is Decentralized Gateway WG, which could benefit from the ability to have a single round-trip that includes full or partial CAR with content + ipns-record.
Broad strokes UX we want to accommodate:
Initial notes / subtasks
ipns-recordcodec, to indicate special meaning of this additional block. Done: Add IPNS Record code multiformats/multicodec#312/ipns/{libp2p-key}paths: decide if returned CAR should include two roots. One for data, second foripns-recordblock. Specify if ipfs-records should be at the beginning of the CAR returned by/ipns/{id}?format=car[&something?]- to allow quick validation of response without wasting time for hashing invalid blocks that do not belong to CID in IPNS record.?format=ipns-recordon/ipns/{key}landed in IPIP-351 (spec)import/exportthat operates on content paths (instead of raw dags likeipfs dagversions), include all parent blocks and not just the final terminating element recursively, and be smart enough to useipns-recordand import it to local namesys cache if a block with ipns-record codec is present in a CARStatus as of 2026Q3
Nobody is working on this. Summary of what exists and what is missing, so it can be picked up.
Trustless two-step retrieval works today, over plain HTTP:
GET /ipns/{name}?format=ipns-record(IPIP-351): the client verifies the signature and resolves the record to/ipfs/{cid}, or stops on mismatch.GET /ipfs/{cid}?format=carwithdag-scope,entity-bytesandorder=dfs(IPIP-402): the client verifies each block as it arrives and drops the connection on the first block that fails its hash or is not expected in the DAG.What is missing is the single round trip.
GET /ipns/{name}?format=cartoday returns the CAR of the resolved content without the record, so the client cannot verify the IPNS step from that response alone. The smallest useful shape: a CAR with theipns-recordblock (codec0x0300) first, then the IPIP-402 stream from the root the record points at. The client checks the record before hashing anything else and can drop the connection after the first bad block. Plain HTTP, no new protocol or transport needed.Open questions, unchanged from the list above:
formatvalue or a CAR content-type parameter (IPIP-412 style), so a client can tell a record-first CAR from a plain one served by an older gateway.Kubo side: no content-path
import/exportexists, andipfs dag importdoes not know theipns-recordcodec.