What the validator checks

A UUID string is valid when it passes three tests:

  1. Format — 32 hexadecimal digits arranged as 8-4-4-4-12 with hyphens at the correct positions, for a total of 36 characters
  2. Version — position 13 (the first digit of the third group) must be a digit between 1 and 8
  3. Variant — position 17 (the first digit of the fourth group) must be 8, 9, a, or b, confirming this is an RFC 9562 UUID

Any string that fails one or more of these checks is not a valid UUID.

Valid UUID examples

550e8400-e29b-41d4-a716-446655440000   ✓ v4, variant 'a'
018c4a14-2d91-7abc-8def-000000000001   ✓ v7, variant '8'
6ba7b810-9dad-11d1-80b4-00c04fd430c8   ✓ v1, variant '8'

Invalid UUID examples

550e8400-e29b-41d4-a716-44665544000    ✗ too short (35 chars)
550e8400-e29b-91d4-a716-446655440000   ✗ version '9' not defined
550e8400-e29b-41d4-c716-446655440000   ✗ variant 'c' is reserved
not-a-uuid                             ✗ wrong format entirely

Special cases

Nil UUID

The nil UUID — 00000000-0000-0000-0000-000000000000 — passes format validation but has no version or variant bits set. RFC 9562 defines it as a valid special value representing “no UUID”. Whether to accept it in your application is a domain decision, not a format question.

Max UUID

The max UUID — ffffffff-ffff-ffff-ffff-ffffffffffff — is the opposite sentinel: all bits set to one. Also defined by RFC 9562, also passes format validation.

Case sensitivity

UUIDs are case-insensitive. A1B2C3D4-... and a1b2c3d4-... are the same value. RFC 9562 specifies lowercase as the canonical output form, but validators must accept both.

How to validate a UUID in code

JavaScript / TypeScript

const UUID_REGEX =
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

function isValidUUID(value: string): boolean {
  return UUID_REGEX.test(value);
}

isValidUUID('550e8400-e29b-41d4-a716-446655440000'); // true
isValidUUID('not-a-uuid');                           // false

The regex enforces all three checks: format, version range ([1-8]), and variant bits ([89ab]).

Python

import uuid

def is_valid_uuid(value: str) -> bool:
    try:
        uuid.UUID(value)
        return True
    except ValueError:
        return False

Python’s uuid.UUID() constructor raises ValueError on any malformed input.

Go

import "github.com/google/uuid"

func isValidUUID(s string) bool {
    _, err := uuid.Parse(s)
    return err == nil
}

Database validation

Most databases that have a native UUID type (uuid in PostgreSQL, uniqueidentifier in SQL Server) will reject invalid strings at the storage layer. Use a native type rather than VARCHAR when the column must only ever hold valid UUIDs.

-- PostgreSQL: this will raise an error for invalid UUIDs
INSERT INTO events (id) VALUES ('not-a-uuid');
-- ERROR: invalid input syntax for type uuid: "not-a-uuid"

What validation does not tell you

Frequently asked questions

What does a UUID validator check?

A UUID validator checks three things: that the string matches the 8-4-4-4-12 hexadecimal format, that position 13 (the version digit) is a known version (1–8), and that position 17 (the variant digit) is 8, 9, a, or b — confirming it follows RFC 9562.

Does the nil UUID pass validation?

The nil UUID (00000000-0000-0000-0000-000000000000) is technically valid RFC 9562 — it has the correct format. Most validators flag it as a special case because it represents "no value", not a real identifier. Whether to accept it depends on your application.

Are UUID strings case-sensitive?

No. RFC 9562 specifies that UUID strings are case-insensitive. Both uppercase and lowercase hex digits are valid. By convention most tools output lowercase, but A-F and a-f are equivalent and a validator should accept both.