ramsey/uuid · error · InvalidArgumentException
The byte string received does not conform to the RFC 9562 (f
Error message
The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant
What it means
Rfc4122\Fields validates the variant bits for standard UUIDs: the top bits of clock_seq_hi_and_reserved (first hex character of the UUID's 4th group) must be 10xx, i.e. 8, 9, a, or b. Nil and max UUIDs bypass the check. Bytes whose variant nibble is 0-7 (NCS/reserved), c-d (Microsoft), or e-f (future reserved) are rejected with InvalidArgumentException. Because UuidBuilder wraps failures, this message usually arrives as the message of an UnableToBuildUuidException.
Source
Thrown at src/Rfc4122/Fields.php:64
use VersionTrait;
/**
* @param string $bytes A 16-byte binary string representation of a UUID
*
* @throws InvalidArgumentException if the byte string is not exactly 16 bytes
* @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;
}View on GitHub (pinned to da5b521600)
Solutions
- Validate before parsing: first hex char of the 4th group must be one of 8,9,a,b
- Reject at the boundary by catching UnableToBuildUuidException when parsing untrusted UUID strings
- Treat Microsoft-variant GUIDs (c/d) as Guid via Guid::fromString(), not Uuid::fromString()
Example fix
// before
$uuid = \Ramsey\Uuid\Uuid::fromString($candidate); // variant nibble invalid
// after
function isRfc4122Variant(string $s): bool
{
$c = strtolower(preg_replace('/[^0-9a-f]/i', '', $s)[16] ?? '0');
return in_array($c, ['8', '9', 'a', 'b'], true);
}
$uuid = isRfc4122Variant($candidate)
? \Ramsey\Uuid\Uuid::fromString($candidate)
: throw new InvalidArgumentException('Not an RFC 9562 variant UUID'); Defensive patterns
Strategy: validation
Validate before calling
$hex = strtolower(preg_replace('/[^0-9a-f]/i', '', $candidate));
$variantNibble = $hex[16] ?? '';
if (!in_array($variantNibble, ['8', '9', 'a', 'b'], true)) {
throw new InvalidArgumentException('Not an RFC 9562 variant UUID');
}
$uuid = \Ramsey\Uuid\Uuid::fromString($candidate); Type guard
function isRfc4122VariantString(string $uuid): bool
{
$hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $uuid));
return strlen($hex) === 32
&& in_array($hex[16], ['8', '9', 'a', 'b'], true);
} Try / catch
try {
$uuid = \Ramsey\Uuid\Uuid::fromString($input);
} catch (\Ramsey\Uuid\Exception\UnableToBuildUuidException $e) {
if (str_contains($e->getMessage(), 'variant')) {
// variant bits wrong: 4th group must start with 8/9/a/b
}
} Prevention
- Uuid::isValid() checks format only; also check variant and version nibbles for untrusted input
- Normalize Microsoft-variant GUIDs through Guid::fromString()
- Reject all-f placeholder fixtures in tests in favor of the real Max UUID string
When it happens
Trigger: Uuid::fromString('12345678-1234-4fff-ffff-123456789abc') — the 4th group starts with 'f', so the variant bits are 1111 and parsing throws this error (wrapped by UnableToBuildUuidException). Also direct Rfc4122\Fields construction or custom codecs with non-RFC bytes. Uuid::isValid() passes these strings since it only checks hex format.
Common situations: Parsing log-stripped or hand-typed UUIDs with a typo in the 4th group; accepting IDs from other systems that emit non-RFC variant bits; test fixtures with placeholder hex like all-f; bit-mangling transformations that touch the clock_seq bytes.
Related errors
- The byte string received does not contain a valid RFC 9562 (
- The byte string received does not conform to the RFC 9562 (f
- The byte string received does not contain a valid version
- The byte string must be 16 bytes long; received {} bytes
- The UUID version in the given fields is not supported by thi
AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21).
Data as JSON: /api/errors/6bd1497f3fba4c45.
Report an issue: GitHub.