Skip to content

How to Check UUID Validity in Python

Learn how to validate UUID strings in Python using the built-in uuid module, regular expressions, and strict format checks for API requests, database keys, and user input.

A UUID (Universally Unique Identifier) is a 128-bit label used to uniquely identify objects, records, or entities across distributed systems without requiring a central authority. UUIDs are represented as 32 hexadecimal digits displayed in five groups separated by hyphens, following the pattern 8-4-4-4-12, for example: 550e8400-e29b-41d4-a716-446655440000.

Validating UUIDs is essential when processing API requests, importing data, working with database keys, or handling user input. In this guide, you'll learn multiple ways to check UUID validity in Python, including using the built-in uuid module and regular expressions.

Understanding UUID Versions

Before validating UUIDs, it helps to understand the different versions, as each serves a distinct purpose:

Version Generation Method Use Case
1 Timestamp + host MAC address Time-ordered identifiers
3 MD5 hash of namespace + name Deterministic, name-based
4 Randomly generated General-purpose, most common
5 SHA-1 hash of namespace + name Deterministic, name-based (more secure than v3)

Python's built-in uuid module provides the most reliable way to validate UUIDs. The uuid.UUID() constructor attempts to parse a string into a UUID object. If the string is invalid, it raises a ValueError.

import uuid

def is_valid_uuid(uuid_string, version=None):
    """
    Check if a string is a valid UUID.
    
    Args:
        uuid_string: The string to validate.
        version: Optional UUID version (1, 3, 4, or 5) to validate against.
    
    Returns:
        True if valid, False otherwise.
    """
    try:
        uuid_obj = uuid.UUID(uuid_string)
    except (ValueError, AttributeError):
        return False

    if version is not None:
        return uuid_obj.version == version

    return True


print(is_valid_uuid("550e8400-e29b-41d4-a716-446655440000"))
print(is_valid_uuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))

print(is_valid_uuid("not-a-uuid"))
print(is_valid_uuid("550e8400-e29b-41d4-a716-44665544000Z"))

print(is_valid_uuid("550e8400-e29b-41d4-a716-446655440000", version=4))

Output:

True
True
False
False
True

How It Works

  1. uuid.UUID(uuid_string) attempts to parse the input string.
  2. If the string doesn't conform to UUID format, a ValueError is raised and caught.
  3. If a specific version is provided, the function additionally verifies that the parsed UUID matches that version.

Enforcing the Standard Hyphenated Format

If your application requires UUIDs in the exact 8-4-4-4-12 hyphenated format, compare the normalized output of uuid.UUID() against the original input:

import uuid

def is_valid_uuid_strict(uuid_string, version=None):
    """Validate UUID and ensure it uses the standard hyphenated format."""
    try:
        uuid_obj = uuid.UUID(uuid_string)
    except (ValueError, AttributeError):
        return False

    if str(uuid_obj) != uuid_string.lower().strip():
        return False

    if version is not None:
        return uuid_obj.version == version

    return True


print(is_valid_uuid_strict("550e8400-e29b-41d4-a716-446655440000"))

print(is_valid_uuid_strict("550e8400e29b41d4a716446655440000"))

print(is_valid_uuid_strict("{550e8400-e29b-41d4-a716-446655440000}"))

Output:

True
False
False

Using Regular Expressions

For lightweight validation without importing the uuid module, or when you need to extract UUIDs from text, regular expressions offer a fast alternative:

import re

UUID_PATTERN = re.compile(
    r'^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$',
    re.IGNORECASE
)

def is_valid_uuid_regex(uuid_string):
    """Validate UUID format using a regular expression."""
    return bool(UUID_PATTERN.match(uuid_string))


print(is_valid_uuid_regex("550e8400-e29b-41d4-a716-446655440000"))  # Valid
print(is_valid_uuid_regex("not-a-valid-uuid"))                      # Invalid
print(is_valid_uuid_regex("550e8400-e29b-41d4-a716-44665544000Z"))  # Invalid (Z)
print(is_valid_uuid_regex("550e8400e29b41d4a716446655440000"))      # Invalid (no hyphens)

Output:

True
False
False
False

Pattern breakdown:

Segment Meaning
[0-9a-f]{8} First group: 8 hex characters
[0-9a-f]{4} Second group: 4 hex characters
[1-5][0-9a-f]{3} Third group: version digit (1–5) + 3 hex characters
[89ab][0-9a-f]{3} Fourth group: variant digit (8, 9, a, or b) + 3 hex characters
[0-9a-f]{12} Fifth group: 12 hex characters

Extracting UUIDs from Text

If you need to find and validate UUIDs embedded within larger text (such as log files or API responses), use re.findall():

import re
import uuid

def is_valid_uuid(uuid_string, version=None):
    """
    Check if a string is a valid UUID.
    
    Args:
        uuid_string: The string to validate.
        version: Optional UUID version (1, 3, 4, or 5) to validate against.
    
    Returns:
        True if valid, False otherwise.
    """
    try:
        uuid_obj = uuid.UUID(uuid_string)
    except (ValueError, AttributeError):
        return False

    if version is not None:
        return uuid_obj.version == version

    return True

text = """
Request ID: 550e8400-e29b-41d4-a716-446655440000
Session: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
Invalid ref: not-a-uuid-value
Trace: 123e4567-e89b-12d3-a456-426614174000
"""

UUID_PATTERN = re.compile(
    r'[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}',
    re.IGNORECASE
)

found_uuids = UUID_PATTERN.findall(text)

for uid in found_uuids:
    print(f"Found: {uid} (valid: {is_valid_uuid(uid)})")

Output:

Found: 550e8400-e29b-41d4-a716-446655440000 (valid: True)
Found: 6ba7b810-9dad-11d1-80b4-00c04fd430c8 (valid: True)
Found: 123e4567-e89b-12d3-a456-426614174000 (valid: True)

Validating UUID Version Specifically

When your application requires a specific UUID version, validate both the format and the version number:

import uuid

def validate_uuid_version(uuid_string, required_version):
    """Validate that a UUID string is valid and matches the required version."""
    try:
        uuid_obj = uuid.UUID(uuid_string)
    except ValueError:
        return False, "Invalid UUID format"

    if uuid_obj.version != required_version:
        return False, f"Expected version {required_version}, got version {uuid_obj.version}"

    return True, f"Valid UUID v{required_version}"


test_cases = [
    ("550e8400-e29b-41d4-a716-446655440000", 4),
    ("6ba7b810-9dad-11d1-80b4-00c04fd430c8", 1),
    ("550e8400-e29b-41d4-a716-446655440000", 1),  # Wrong version
]

for uid, version in test_cases:
    is_valid, message = validate_uuid_version(uid, version)
    status = "✅" if is_valid else "❌"
    print(f"{status} {uid} (v{version}): {message}")

Output:

✅ 550e8400-e29b-41d4-a716-446655440000 (v4): Valid UUID v4
✅ 6ba7b810-9dad-11d1-80b4-00c04fd430c8 (v1): Valid UUID v1
❌ 550e8400-e29b-41d4-a716-446655440000 (v1): Expected version 1, got version

Quick Comparison of Methods

Method Validates Format Validates Version Strict Format Performance
uuid.UUID() ✅ ✅ (with check) ❌ (lenient) Fast
uuid.UUID() + string comparison ✅ ✅ ✅ Fast
Regular expression ✅ ✅ (pattern-based) ✅ ⚡ Fastest

Conclusion

Python provides flexible tools for validating UUIDs:

  • uuid.UUID() is the recommended approach for most cases. It's reliable, handles multiple formats, and lets you verify the UUID version.
  • Add a string comparison (str(uuid_obj) == input) when you need to enforce the exact hyphenated format.
  • Regular expressions are ideal for lightweight format validation, extracting UUIDs from text, or scenarios where you want to avoid constructing UUID objects.

For production applications, always validate UUIDs at your system boundaries, API endpoints, form inputs, and data imports, to catch malformed identifiers before they cause downstream errors.

Navigation