{"record":{"id":"407a22150ce23208","repo":"ramsey/uuid","slug":"the-byte-string-received-does-not-contain-a-valid-407a22","errorCode":null,"errorMessage":"The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version","messagePattern":"The byte string received does not contain a valid RFC 9562 \\(formerly RFC 4122\\) version","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Rfc4122/Fields.php","lineNumber":70,"sourceCode":"     * @throws InvalidArgumentException if the byte string does not represent an RFC 9562 (formerly RFC 4122) UUID\n     * @throws InvalidArgumentException if the byte string does not contain a valid version\n     */\n    public function __construct(private string $bytes)\n    {\n        if (strlen($this->bytes) !== 16) {\n            throw new InvalidArgumentException(\n                'The byte string must be 16 bytes long; ' . 'received ' . strlen($this->bytes) . ' bytes',\n            );\n        }\n\n        if (!$this->isCorrectVariant()) {\n            throw new InvalidArgumentException(\n                'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant',\n            );\n        }\n\n        if (!$this->isCorrectVersion()) {\n            throw new InvalidArgumentException(\n                'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version',\n            );\n        }\n    }\n\n    /**\n     * @pure\n     */\n    public function getBytes(): string\n    {\n        return $this->bytes;\n    }\n\n    public function getClockSeq(): Hexadecimal\n    {\n        if ($this->isMax()) {\n            $clockSeq = 0xffff;\n        } elseif ($this->isNil()) {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/ramsey/uuid/blob/da5b521600a707d2dd097598464bd3090de850f5/src/Rfc4122/Fields.php#L52-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n$uuid = \\Ramsey\\Uuid\\Uuid::fromString($id); // version nibble invalid\n\n// after\n$hex = strtolower(preg_replace('/[^0-9a-f]/i', '', $id));\n$version = hexdec($hex[12] ?? '0');\n$special = $hex === str_repeat('0', 32) || $hex === str_repeat('f', 32);\nif (!$special && ($version < 1 || $version > 8)) {\n    throw new InvalidArgumentException('Not an RFC 9562 version UUID');\n}\n$uuid = \\Ramsey\\Uuid\\Uuid::fromString($id);","handlingStrategy":"validation","validationCode":"$hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $candidate));\n$version = hexdec($hex[12] ?? '0');\n$special = $hex === str_repeat('0', 32) || $hex === str_repeat('f', 32);\nif (!$special && ($version < 1 || $version > 8)) {\n    throw new InvalidArgumentException('Invalid UUID version nibble');\n}\n$uuid = \\Ramsey\\Uuid\\Uuid::fromString($candidate);","typeGuard":"function hasValidRfc4122Version(string $uuid): bool\n{\n    $hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $uuid));\n    if (strlen($hex) !== 32) {\n        return false;\n    }\n    if ($hex === str_repeat('0', 32) || $hex === str_repeat('f', 32)) {\n        return true; // nil / max\n    }\n    $v = hexdec($hex[12]);\n    return $v >= 1 && $v <= 8;\n}","tryCatchPattern":"try {\n    $uuid = \\Ramsey\\Uuid\\Uuid::fromString($input);\n} catch (\\Ramsey\\Uuid\\Exception\\UnableToBuildUuidException $e) {\n    if (str_contains($e->getMessage(), 'version')) {\n        // version nibble outside 1-8\n    }\n}","preventionTips":["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"],"tags":["php","ramsey-uuid","version-nibble","rfc-9562","parsing","schema-validation"],"backgroundTag":"uuid-version-validation-failed","analyzedSha":"da5b521600a707d2dd097598464bd3090de850f5","analyzedAt":"2026-08-21T01:35:29.252Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}