None of these mistakes are exotic — they're the kind of thing that works fine in a demo, then causes a slow index, a support ticket, or a confused code review six months later. Below is what tends to go wrong, and a practical way to check for it, illustrated with an ordinary example scenario: a small team building an internal tool that assigns IDs to imported records.
1. Storing UUIDs as plain text when a native type is available
It's an easy default: a UUID looks like a string, so it gets a VARCHAR(36) column. This works, but it isn't free. As a hypothetical example, imagine a table with 5 million rows using a text UUID primary key versus the same table with a native binary UUID type — the text version's index will typically occupy noticeably more disk space and can be slower to compare byte-by-byte during joins, simply because the database is treating a fixed-size 128-bit value as variable-length text. PostgreSQL has a dedicated uuid type; MySQL commonly stores UUIDs as BINARY(16) (sometimes reordered for better index locality); most ORMs can map a UUID field to whichever native type the underlying database supports. If your platform doesn't have a native type, at minimum store the value without hyphens or braces to save a few bytes per row.
2. Assuming a v1 UUID is privacy-safe because it "looks random"
This is a case where the string itself gives no visual warning. A v1 and a v4 UUID are both 36 characters of hex and hyphens, and to a human eye they look equally "random." But under the hood a v1 UUID's first three groups encode a 100-nanosecond-precision timestamp, and its node field can carry a real MAC address if generated by software following the original spec on physical hardware. That means a leaked v1 UUID can, in principle, reveal roughly when a record was created and which machine generated it — information a v4 UUID never carries. If you're issuing IDs that end up visible to end users (order numbers, share links, public API IDs), v4 or v7 is the safer default; reserve v1-style generation for internal systems where that extra information isn't a liability. Note that a browser-based generator can't access a real network card at all, so any "v1-like" mode there necessarily substitutes a randomly generated node value — which closes the MAC-leak issue specifically, but the embedded timestamp is still present.
3. Mixing up v3 (MD5) and v5 (SHA-1) across a system
Consider a hypothetical scenario: a data pipeline generates a deterministic ID for each imported product by hashing a namespace UUID together with the product's SKU. If the import script uses v5 (SHA-1) but a downstream reconciliation job was written months later using v3 (MD5) — perhaps because a developer copied an old code snippet — the two systems will generate different UUIDs for the identical SKU, and matching records will simply fail to line up. Nothing throws an error; the IDs are just quietly wrong. Since v5 is generally recommended over v3 for new work (SHA-1 has fewer known weaknesses than MD5, even though neither is being used here for cryptographic security), it's worth standardizing on v5 explicitly in code comments or a shared constant, rather than leaving the algorithm choice implicit.
4. Fighting format mismatches instead of normalizing on the way in
A UUID's canonical form is 36 characters (8-4-4-4-12, lowercase, hyphenated), but plenty of systems hand you something else: a .NET API might return one wrapped in braces, a URI might carry a urn:uuid: prefix, a spreadsheet export might strip hyphens, and a case-insensitive system might return uppercase hex. If your code compares two UUID strings directly without stripping braces/prefixes and lowercasing both sides first, values that are logically identical can compare as unequal. The fix is to normalize on input — strip non-hex formatting characters, lowercase, and re-insert hyphens in the standard positions — rather than special-casing every format you happen to encounter later. A validator that accepts multiple input shapes (hyphenated, non-hyphenated, braced, urn-prefixed) and reports back the canonical form is a fast way to check whether two values you suspect are "the same UUID" actually are.
5. Misjudging collision risk in either direction
There are two opposite mistakes here. The first is over-worrying about v4 collisions — for example, adding a "check if this UUID already exists" retry loop for newly generated v4 IDs as if collisions were a realistic operational concern; with 122 random bits, that safeguard adds complexity without meaningfully improving reliability for the vast majority of applications. The second, subtler mistake is treating a v3/v5 "collision" as a bug: if your deterministic ID generator produces the exact same UUID for the exact same namespace+name input every single time, that's the entire point of using a name-based version instead of a random one — it's what allows a re-run import job to recognize "I've already created an ID for this record" instead of creating duplicates.