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) |
Using the uuid Module (Recommended)
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
TrueHow It Works
uuid.UUID(uuid_string)attempts to parse the input string.- If the string doesn't conform to UUID format, a
ValueErroris raised and caught. - If a specific
versionis 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
FalseUsing 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
FalsePattern 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 versionQuick 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.