How to Validate a UUID List: Format Rules and Cleaning Bad Rows
Validate UUIDs by the 8-4-4-4-12 hex rule, spot malformed rows, and clean a pasted UUID list with a reason beside every flagged line.
How to Validate a UUID List: Format Rules and Cleaning Bad Rows
A UUID looks simple until you have a few hundred of them pasted from a CSV export, a support ticket, and a copied web page, and one of them quietly breaks an import. The fix is boring but reliable: check every line against the actual format rules before you trust the list. This guide walks through what makes a UUID well-formed, what counts as malformed, and how to clean a mixed list so the rows that survive are safe to paste into a script, a SQL IN clause, or an allowlist.
What a canonical UUID actually is
A canonical UUID is 32 hexadecimal digits, written in five groups separated by hyphens in the pattern 8-4-4-4-12. That is the whole shape: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where every x is one of 0-9 or a-f (case-insensitive). A real example:
3f9a2c10-7b41-4d22-8e5f-1a2b3c4d5e6f
Count it and you get eight, four, four, four, and twelve hex digits, with hyphens only at positions 9, 14, 19, and 24. Get any of that wrong and the string is not a valid UUID, even if it "looks close." The three ways a row goes bad are:
- A non-hex character. Anything outside
0-9a-fafter the hyphens are removed. The lettergis the classic offender, and so is a stray space pasted from a spreadsheet cell. - Wrong group lengths. A group with seven or nine digits instead of eight, or a final group that is eleven digits long.
- Missing or misplaced hyphens. A bare 32-character string with no hyphens, or hyphens in the wrong spots, both fail the canonical shape.
Does this tool also check version and variant?
Yes, and this is the part people miss. The UUID List Validator does not stop at the 8-4-4-4-12 shape. It also looks at the version nibble — the first digit of the third group — and rejects a row whose version digit falls outside 1 to 5. So a string that is perfectly shaped but carries a version of 0 or 7 in that slot is flagged, not passed. The reason column names the exact check that failed, including "version digit outside 1 to 5," so you are never left guessing whether the problem was a typo or an out-of-range version.
That matters because a lot of fake or hand-edited UUIDs are shape-correct but semantically junk. Checking the version nibble catches IDs that no real generator (v1 time-based, v3/v5 namespace, v4 random) would ever emit. The validator marks each line pass or fail and runs the whole thing in your browser — nothing is uploaded.
A worked example: a mixed list
Here is the kind of list that lands in front of me on a normal cleanup task. Paste it in and each row comes back with a verdict and a reason:
Input:
3f9a2c10-7b41-4d22-8e5f-1a2b3c4d5e6f
3F9A2C10-7B41-4D22-8E5F-1A2B3C4D5E6F
9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d
123e4567-e89b-12d3-a456-426614174zzz
00000000-0000-7000-8000-000000000000
3f9a2c10-7b41-4d22-8e5f
Output:
| Row | Verdict | Reason | |-----|---------|--------| | 3f9a2c10-7b41-4d22-8e5f-1a2b3c4d5e6f | pass | OK | | 3F9A2C10-7B41-4D22-8E5F-1A2B3C4D5E6F | pass | OK (case-insensitive) | | 9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d | fail | missing hyphens / wrong shape | | 123e4567-e89b-12d3-a456-426614174zzz | fail | non-hex character (z) | | 00000000-0000-7000-8000-000000000000 | fail | version digit outside 1 to 5 | | 3f9a2c10-7b41-4d22-8e5f | fail | wrong length (only four groups) |
Two pass, four fail. Notice the second row: it is the same value as the first in uppercase, which is valid — UUID hex is case-insensitive — but if you also enable dedupe with normalization, the two collapse to one. The fifth row is the sneaky one: textbook 8-4-4-4-12 shape, all hex, yet it carries version 7 and gets flagged by the version check rather than the shape check.
Cleaning the list, not just judging it
Validation that only prints "12 errors" wastes your time. What you usually want is the clean list out the other side, ready to use. After the rows are checked, you can keep unique rows only, sort the normalized output, and switch the export between plain lines, CSV, JSON, Markdown, SQL IN, and a TypeScript union. So a column of raw, mixed-case, partly-broken IDs becomes a deduped, sorted SQL IN (...) block with no hand-added quotes or trailing commas.
You can also choose to keep the invalid rows in the output for review instead of silently dropping them. That is the difference between "I deleted the bad ones" and "here is exactly which rows failed and why" — the second one survives a code review. When I am prepping an allowlist before a release, I paste the raw export, turn on "keep invalid rows," and download a CSV with line numbers. Then I can go back to whoever sent me the file and point at row 47 instead of arguing about whether the list was clean. It has saved me an embarrassing import more than once.
Common traps worth naming
A few things bite people repeatedly:
- Hidden whitespace from copied web text. Pages and rich-text editors love to inject non-breaking spaces and zero-width characters. Normalize before you dedupe or import, or two "identical" UUIDs will refuse to match.
- Validation is not existence. A UUID passing the format check tells you the string is well-formed. It does not tell you the record, account, or resource behind it still exists. Treat format and reality as two separate questions.
- Keep an audit trail. When the result feeds compliance or a migration, download CSV or Markdown with line numbers rather than copying only the final cleaned column. Future-you will want to see what was dropped.
If your job is to pull the IDs out of a noisy blob first, reach for the UUID Extractor to lift them from logs or HTML, then bring the resulting list here to validate and clean it. The two tools chain naturally: extract, then verify against the 8-4-4-4-12 plus version rules above.
UUIDs are designed to be unique and collision-resistant, which is exactly why a single malformed one is so easy to overlook and so annoying when it slips through. A two-minute pass that checks shape, hex, hyphens, and the version nibble — and hands you a reason next to every reject — turns a fragile copy-paste into a list you can actually trust.
Made by Toolora · Updated 2026-06-13