ramsey/uuid · error · InvalidArgumentException

The byte string must be 16 bytes long; received {} bytes

Error message

The byte string must be 16 bytes long; received {} bytes

What it means

Rfc4122\Fields is built by Rfc4122\UuidBuilder for every standard UUID decode. Its first validation is structural: the binary representation must be exactly 16 bytes; any other length throws InvalidArgumentException before variant and version checks run. The two string-concatenated literal halves make this message easy to spot in logs.

Source

Thrown at src/Rfc4122/Fields.php:58

final class Fields implements FieldsInterface
{
    use MaxTrait;
    use NilTrait;
    use SerializableFieldsTrait;
    use VariantTrait;
    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',
            );
        }
    }

    /**

View on GitHub (pinned to da5b521600)

Solutions

  1. Assert strlen($bytes) === 16 before building fields or custom codec decode
  2. When converting from hex, validate the hex is exactly 32 characters before hex2bin()
  3. Use Uuid::fromString()/fromBytes() so the standard codecs validate with their own clear errors

Example fix

// before
$uuid = $builder->build($codec, hex2bin($hex)); // $hex may be 30 chars

// after
if (strlen($hex) !== 32 || !ctype_xdigit($hex)) {
    throw new InvalidArgumentException('UUID hex must be exactly 32 hex chars');
}
$uuid = $builder->build($codec, hex2bin($hex));
Defensive patterns

Strategy: validation

Validate before calling

if (strlen($bytes) !== 16) {
    throw new InvalidArgumentException('UUID bytes must be exactly 16, got ' . strlen($bytes));
}
$fields = new \Ramsey\Uuid\Rfc4122\Fields($bytes);

Type guard

function isSixteenByteString(string $bytes): bool
{
    return strlen($bytes) === 16;
}

Try / catch

try {
    $uuid = \Ramsey\Uuid\Uuid::fromBytes($bytes);
} catch (\Ramsey\Uuid\Exception\InvalidArgumentException $e) {
    // '$bytes string should contain 16 characters.' from the codec, or fields error
}

Prevention

When it happens

Trigger: Constructing Rfc4122\Fields directly or calling Rfc4122\UuidBuilder::build($codec, $bytes) with bytes whose length is not 16 — hex2bin() of a hex string that is not exactly 32 chars, truncated binary payloads, or custom codecs that pass modified byte strings. The public Uuid::fromBytes() path usually throws a codec-level 16-character error first, so this fires mainly on custom/builder paths.

Common situations: Custom codecs or byte-mangling middleware (compression, encryption) changing payload length; BLOB columns with wrong size; unit tests constructing fields from hand-written byte strings.

Related errors


AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21). Data as JSON: /api/errors/8791bddde6f58770. Report an issue: GitHub.