ramsey/uuid · error · InvalidArgumentException

$bytes string should contain 16 characters.

Error message

$bytes string should contain 16 characters.

What it means

StringCodec::decodeBytes() is the standard binary decode path (used by Uuid::fromBytes()); it builds a UUID from a raw byte string and throws InvalidArgumentException when strlen($bytes) !== 16. The bytes must be the plain 16-octet RFC 4122 representation with no encoding or formatting applied.

Source

Thrown at src/Codec/StringCodec.php:86

        /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */
        return $uuid->getFields()->getBytes();
    }

    /**
     * @throws InvalidUuidStringException
     *
     * @inheritDoc
     */
    public function decode(string $encodedUuid): UuidInterface
    {
        /** @phpstan-ignore possiblyImpure.methodCall */
        return $this->builder->build($this, $this->getBytes($encodedUuid));
    }

    public function decodeBytes(string $bytes): UuidInterface
    {
        if (strlen($bytes) !== 16) {
            throw new InvalidArgumentException('$bytes string should contain 16 characters.');
        }

        return $this->builder->build($this, $bytes);
    }

    /**
     * Returns the UUID builder
     */
    protected function getBuilder(): UuidBuilderInterface
    {
        return $this->builder;
    }

    /**
     * Returns a byte string of the UUID
     */
    protected function getBytes(string $encodedUuid): string
    {

View on GitHub (pinned to da5b521600)

Solutions

  1. Convert first: (string) hex2bin($hex) / base64_decode($b64), then check strlen === 16.
  2. Pre-validate length before fromBytes()/decodeBytes().
  3. Use BINARY(16) storage so values arrive as exactly 16 raw bytes.

Example fix

// before
$uuid = Uuid::fromBytes($hexFromDb); // 32 hex chars -> InvalidArgumentException

// after
$bytes = (string) hex2bin($hexFromDb);
$uuid = Uuid::fromBytes($bytes); // strlen === 16
Defensive patterns

Strategy: validation

Validate before calling

function normalizeTo16Bytes(string $value): string
{
    if (strlen($value) === 32 && ctype_xdigit($value)) {
        $value = (string) hex2bin($value);
    }
    if (strlen($value) !== 16) {
        throw new InvalidArgumentException(sprintf('expected 16 bytes, got %d', strlen($value)));
    }

    return $value;
}

$uuid = Uuid::fromBytes(normalizeTo16Bytes($value));

Type guard

function isUuidByteString(string $value): bool
{
    return strlen($value) === 16;
}

Try / catch

try {
    $uuid = Uuid::fromBytes($bytes);
} catch (\Ramsey\Uuid\Exception\InvalidArgumentException $e) {
    throw new StoredIdentifierCorruptException($row['id'], $e);
}

Prevention

When it happens

Trigger: Uuid::fromBytes($value) where $value is a 32-char hex string, a hyphenated UUID string, base64, or a truncated/oversized binary value.

Common situations: Column stored as CHAR(36)/hex instead of BINARY(16); forgetting hex2bin() after hex transport; ORM or DBAL returning a formatted string for binary columns; substr() bugs cutting bytes.

Related errors


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