ramsey/uuid · error · InvalidArgumentException
The byte string received does not contain a valid RFC 9562 (
Error message
The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version
What it means
Rfc4122\Fields (via VersionTrait::isCorrectVersion) requires the version nibble — first hex character of the 3rd group — to be 1 through 8 for non-nil/non-max UUIDs. Version 0 or 9-f means the value does not follow RFC 9562's version field, so the constructor throws InvalidArgumentException; through the standard parse path this message is carried by a wrapping UnableToBuildUuidException.
Source
Thrown at src/Rfc4122/Fields.php:70
* @throws InvalidArgumentException if the byte string does not represent an RFC 9562 (formerly RFC 4122) UUID
* @throws InvalidArgumentException if the byte string does not contain a valid version
*/
public function __construct(private string $bytes)
{
if (strlen($this->bytes) !== 16) {
throw new InvalidArgumentException(
'The byte string must be 16 bytes long; ' . 'received ' . strlen($this->bytes) . ' bytes',
);
}
if (!$this->isCorrectVariant()) {
throw new InvalidArgumentException(
'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant',
);
}
if (!$this->isCorrectVersion()) {
throw new InvalidArgumentException(
'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version',
);
}
}
/**
* @pure
*/
public function getBytes(): string
{
return $this->bytes;
}
public function getClockSeq(): Hexadecimal
{
if ($this->isMax()) {
$clockSeq = 0xffff;
} elseif ($this->isNil()) {View on GitHub (pinned to da5b521600)
Solutions
- Pre-check the version nibble: hex char at index 12 must be 1-8 (or the value is all-zero/all-f)
- Catch UnableToBuildUuidException where untrusted UUID strings enter the system and reject with a domain-specific error
- For deliberately arbitrary 128-bit values, use Ulid or keep them as Hexadecimal instead of Uuid
Example fix
// before
$uuid = \Ramsey\Uuid\Uuid::fromString($id); // version nibble invalid
// after
$hex = strtolower(preg_replace('/[^0-9a-f]/i', '', $id));
$version = hexdec($hex[12] ?? '0');
$special = $hex === str_repeat('0', 32) || $hex === str_repeat('f', 32);
if (!$special && ($version < 1 || $version > 8)) {
throw new InvalidArgumentException('Not an RFC 9562 version UUID');
}
$uuid = \Ramsey\Uuid\Uuid::fromString($id); Defensive patterns
Strategy: validation
Validate before calling
$hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $candidate));
$version = hexdec($hex[12] ?? '0');
$special = $hex === str_repeat('0', 32) || $hex === str_repeat('f', 32);
if (!$special && ($version < 1 || $version > 8)) {
throw new InvalidArgumentException('Invalid UUID version nibble');
}
$uuid = \Ramsey\Uuid\Uuid::fromString($candidate); Type guard
function hasValidRfc4122Version(string $uuid): bool
{
$hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $uuid));
if (strlen($hex) !== 32) {
return false;
}
if ($hex === str_repeat('0', 32) || $hex === str_repeat('f', 32)) {
return true; // nil / max
}
$v = hexdec($hex[12]);
return $v >= 1 && $v <= 8;
} Try / catch
try {
$uuid = \Ramsey\Uuid\Uuid::fromString($input);
} catch (\Ramsey\Uuid\Exception\UnableToBuildUuidException $e) {
if (str_contains($e->getMessage(), 'version')) {
// version nibble outside 1-8
}
} Prevention
- Validate the 3rd group's first hex character when ingesting external IDs
- Do not generate 128-bit identifiers by random hex and call them UUIDs
- Reserve UuidV8 (version 8) for custom layouts instead of inventing version nibbles
When it happens
Trigger: Uuid::fromString('12345678-1234-fabc-9abc-123456789abc') — the 3rd group starts with 'f' (version 15), so parsing throws. Likewise versions 0 and 9-e. Direct Rfc4122\Fields construction or custom builders with such bytes hit the same check. Uuid::isValid() does not catch this because it only validates hex layout.
Common situations: Placeholder/test UUIDs like 'ffffffff-ffff-ffff-...' (non-max misuse); IDs from systems that fill the version field freely (some legacy GUID generators); typo'd constants; bit-shifting bugs in custom encoding code.
Related errors
- The byte string received does not contain a valid version
- The byte string received does not conform to the RFC 9562 (f
- The UUID version in the given fields is not supported by thi
- The byte string received does not conform to the RFC 9562 (f
- The byte string must be 16 bytes long; received {} bytes
AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21).
Data as JSON: /api/errors/407a22150ce23208.
Report an issue: GitHub.