The six UUID versions, ranked by security and privacy
The UUID format is defined by RFC 9562 (published May 2024, replacing the older RFC 4122). All versions are 128 bits, formatted as xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx, where M marks the version and N marks the variant. What differs is where the other 122 bits come from — and that difference is the entire security and privacy story.
| Version | How it's built | Random bits | Leaks | Guessable? | Use it for |
|---|---|---|---|---|---|
| v1 | 48-bit MAC + 60-bit timestamp + clock seq | ~14 | MAC address + creation time | Partly (time is sequential) | Legacy systems only; avoid |
| v3 | MD5 hash of namespace + name | 0 | The input, if input space is small | Yes, if input is known | Deterministic IDs, never secrets |
| v4 | Random | 122 | Nothing | No (with a CSPRNG) | General IDs, tokens, keys |
| v5 | SHA-1 hash of namespace + name | 0 | The input, if input space is small | Yes, if input is known | Deterministic IDs, never secrets |
| v6 | Reordered v1 (time-sortable) | ~14 | MAC address + creation time | Partly | Time-sortable legacy migration |
| v7 | 48-bit Unix ms timestamp + random | 74 | Creation timestamp | No (random tail), but time is visible | DB primary keys, sortable IDs |
| Which should I use? | — | — | — | — | v4 for anonymous random IDs; v7 for sortable DB keys; never v1/v6 for anything sensitive |
The takeaway: v4 and v7 are the only versions with enough randomness to resist guessing. v3 and v5 are hashes with zero randomness — same input always yields the same UUID, so they are useful for deduplication but must never be treated as secret. v1 and v6 carry a MAC address and timestamp in the clear.
Anatomy of a UUIDv4: which bytes are random, which are fixed
A common misconception is that all 128 bits of a v4 UUID are random. Six of them are not: four bits are pinned to the version (4) and two bits are pinned to the variant (10). Those fixed bits are why every v4 UUID has a 4 at the start of the third group and one of 8, 9, a, or b at the start of the fourth.
Those 122 random bits are what make a v4 UUID unguessable — but only when they are drawn from a cryptographically secure source. That single dependency is where most real-world UUID vulnerabilities live.
The one thing that actually breaks UUID security: the RNG
The version tells you how many bits are supposed to be random. Whether they are random depends entirely on the underlying random number generator. This is the failure mode that turns a "secure" v4 into a predictable token.
Math.random()is not cryptographic. In V8, Node, and every browser,Math.random()is a fast pseudo-random generator (xorshift128+) seeded from a small state. Given a handful of outputs, researchers have reconstructed its internal state and predicted every subsequent value. A UUIDv4 assembled fromMath.random()bytes inherits that predictability — the 122 "random" bits are an illusion.- Use the platform CSPRNG. In modern environments call
crypto.randomUUID()(Node 16.7+, all current browsers, Deno, Bun). It draws from the OS cryptographically secure RNG and returns a compliant v4 in one line. For raw bytes, usecrypto.getRandomValues()(browser) orcrypto.randomBytes()(Node). - Old libraries and forks are the risk. Some legacy
uuidpolyfills, homegrown implementations, and copied Stack Overflow snippets fall back toMath.random()when no crypto API is found. That fallback is silent — the UUID still looks perfectly formatted.
If you generate a UUID and hand it out as a password-reset link, an unguessable value is the whole point. A predictable RNG quietly removes that guarantee while leaving the output looking identical.
The privacy leak: how a UUID caught a virus author
In 1999 the Melissa macro virus spread through infected Word documents. Microsoft Office at the time embedded a UUIDv1-style GUID in document metadata — and UUIDv1 encodes the network card's MAC address directly in its final 48 bits. Investigators extracted the MAC address from documents linked to the virus, matched it to hardware, and identified the author. His own identifier convicted him.
That is the concrete privacy cost of a time-and-MAC UUID. The lesson generalizes:
If a UUID will ever appear in a document, a URL, a public API response, or a data export, prefer v4 (leaks nothing) or, where sortability matters, v7 (leaks only a timestamp). Reserve v1 and v6 for internal systems that specifically need the node/time fields and where the MAC-address exposure is understood and acceptable.
Identifier versus secret: the distinction that trips teams up
The single most common UUID mistake is conflating two different jobs:
- An identifier must be unique. It is not required to be secret, and in practice it is not — UUIDs show up in URLs, logs, referrer headers, error messages, and analytics. Any version satisfies "unique."
- A secret must be unguessable and confidential. Only a v4 (or v7) from a CSPRNG is unguessable, and confidentiality is your job: don't log it, don't leak it via
Referer, expire it.
Problems appear when a team uses a UUID as a capability — "if you know the URL, you're authorized" — without checking which version it is. A predictable v1 or a deterministic v5 used as a password-reset token is a real vulnerability, because the value can be reconstructed rather than guessed. A v4 from crypto.randomUUID() can safely double as a secret, provided you also treat it like one: short expiry, single use, never written to logs. For genuinely long-lived secrets, a dedicated 256-bit random token is cleaner than borrowing a UUID for the role.
Practical recommendations
- Default to v4 for anonymous identifiers and any value that might be exposed. It leaks nothing and is unguessable with a proper RNG.
- Use v7 for database primary keys when you want time-sortable, index-friendly IDs — but remember the embedded timestamp is readable by anyone who holds the ID.
- Never assemble UUIDs from
Math.random(). Callcrypto.randomUUID()orcrypto.getRandomValues(). Audit old dependencies for silentMath.random()fallbacks. - Avoid v1 and v6 in anything user-facing; they broadcast a MAC address and creation time.
- Treat v3/v5 as public. They are deterministic hashes — useful for dedup, useless as secrets.
- If a UUID grants access, treat it as a secret: CSPRNG source, expiry, single use, and keep it out of logs and referrer headers.
Generate and inspect a few versions with the tool above, or read our v1 / v4 / v5 version comparison for a deeper field-by-field breakdown. All generation in our tool happens client-side via the browser's native crypto API, so no value is ever transmitted to a server.