Logo
Blockchain · Developer

IPFS CID Explained: CIDv0 vs CIDv1, Multibase & Multihash

01/11/2026
IPFS CID anatomy — multibase prefix, version, multicodec, and multihash digest

Anatomy of a CIDv1: a self-describing content identifier, layer by layer.

A CID — Content Identifier — is the single value at the heart of IPFS. It is not a URL and not just a hash: it is a self-describing address that encodes which algorithm produced the fingerprint, which format the content is in, and how the string itself is encoded. Understanding how a CID is put together explains most of the "why does my CID look different" problems developers hit when pinning, sharing, or verifying IPFS content. This guide breaks down the anatomy, the difference between CIDv0 and CIDv1, and when you can (and cannot) convert between them.

The Anatomy of a CIDv1

Take a typical CIDv1 like bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi. Stripped of its string encoding, it is a sequence of bytes made of four parts:

LayerValue in this CIDWhat it tells you
Multibase prefixb = base32How to decode the string back into bytes
Version1Which CID layout is in use (0 or 1)
Multicodec0x70 = dag-pbThe format of the addressed content
Multihashsha2-256, 32-byte digestHash function code, digest length, and the digest itself

The multibase prefix is one character: b for base32, z for base58btc, f for hex, k for base36. The multicodec describes the content format — dag-pb (0x70) for standard IPFS file structures, raw (0x55) for plain byte blocks, dag-cbor (0x71) for structured data, libp2p-key (0x72) for IPNS names. The multihash is itself two varints plus bytes: the hash function code (sha2-256 is 0x12), the digest length, and the digest.

Paste any CID into our IPFS CID Inspector to see this breakdown live — it decodes every layer, shows the hex digest, and flags weak hash functions.

CIDv0 vs CIDv1

CIDv0 predates all this machinery. It is simply the base58btc encoding of a bare multihash — which is why every CIDv0 is exactly 46 characters starting with Qm, and why it can only ever describe a dag-pb object with a sha2-256 digest. CIDv1 generalizes the format: any codec, any hash function, any string encoding.

CIDv0CIDv1
ExampleQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnRbafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
Encodingbase58btc onlyAny multibase (base32 default)
Codecdag-pb impliedExplicit (raw, dag-cbor, …)
Hashsha2-256 onlyAny multihash function
Subdomain gatewaysNo (uppercase letters)Yes — lowercase base32
Default todayLegacy toolingKubo, Helia, pinning services

The two examples in the table encode the same digest — QmbWqx… and bafybei… are the same content addressed two ways. Converting v0 → v1 always works. Converting v1 → v0 only works for dag-pb CIDs with a 32-byte sha2-256 digest; anything else has no v0 representation. The inspector tool linked above performs both conversions and shows the base36 "subdomain-optimized" form as well.

Why the Same File Gets Different CIDs

The most common CID confusion: two people add identical bytes to IPFS and get different CIDs. The digest depends on the import settings, not just the content:

  • CID version — the same DAG hashed as v0 or v1 produces different strings.
  • Raw leaves — modern ipfs add stores leaf blocks as raw codec; older versions wrapped them in dag-pb protobufs. Different codec, different CID.
  • Wrap with directory — ipfs add -w makes the root a folder containing your file, so the filename itself enters the hash.
  • Chunker — files above 256 KiB are split into a DAG; a different chunking strategy produces a different root.

To predict the CID before uploading, use our IPFS CID Generator — it runs the same UnixFS chunking and hashing as ipfs add entirely in your browser, with CIDv0/CIDv1 profiles and wrap-in-directory options, and shows the equivalent CLI command.

From CID to Content: Gateways

A CID names content; it does not host it. Retrieval happens through an IPFS node or an HTTP gateway, which exposes two URL forms: path-style (https://ipfs.io/ipfs/<cid>) and subdomain-style (https://<cid>.ipfs.dweb.link). Subdomain URLs give each CID its own origin — required for sites with relative links — but need a DNS-safe name: lowercase and ≤63 characters. That is why subdomain gateways require the base32 CIDv1 form, and why CIDv0 (which contains uppercase letters) can never be used that way.

Two frequent real-world needs: converting an ipfs:// URI from an NFT or SDK into a shareable HTTPS link, and checking whether a CID is actually retrievable before you send the link to someone. Our IPFS URL Converter handles the first — it accepts URIs, bare CIDs, and both gateway styles and emits every equivalent form. The IPFS Gateway Checker handles the second — it probes major public gateways and reports status and latency for each.

Pitfalls Worth Knowing

  • A valid CID is not a promise of availability. Nothing about the string tells you anyone is serving the content — if nothing pins it, every gateway returns 404. Validity and retrievability are different questions.
  • CIDs are case-sensitive in context. base32 CIDv1 strings are lowercase by spec; treat any uppercase form as non-canonical.
  • libp2p-key CIDs are IPNS names. A CID whose codec is libp2p-key (starting k51…) addresses a mutable pointer, not fixed content — the content it resolves to can change.
  • Public gateways are best-effort. They rate-limit, go offline, and can be flagged for phishing. For anything that matters, pin the content and prefer a dedicated or self-hosted gateway.

Frequently Asked Questions

Is a CID the same as an IPFS hash?

Informally yes — people say "IPFS hash" for what is technically a CID. Precisely, the CID wraps the hash: it carries the multihash digest plus the version, codec, and encoding metadata that make it self-describing.

Can I convert a CIDv1 back to CIDv0?

Only if it is a dag-pb CID with a 32-byte sha2-256 digest — the exact constraints CIDv0 was built around. Raw, dag-cbor, or non-SHA-256 CIDs have no v0 form. Our CID Inspector shows the v0 string whenever one exists.

Why does my CID start with "bafy", "bafk", or "Qm"?

The prefix reveals the format: Qm means CIDv0 (base58btc, dag-pb implied); bafy… is a CIDv1 in base32 with the dag-pb codec; bafk… is a CIDv1 in base32 with the raw codec; k51… is a libp2p-key CID used as an IPNS name.

Does computing a CID publish my file?

No. A CID is just a fingerprint — computing it locally changes nothing on the network. Content only becomes retrievable when a node or pinning service actually provides it, which is why a freshly generated CID will 404 on every gateway until you pin it.

Share:

Related Insights

Privacy & Cookie Preferences

We use cookies to enhance your experience, analyze site performance, and support our marketing efforts. Your privacy matters, and you can withdraw consent at any time.