ramsey/uuid · error · InvalidArgumentException
The byte string must be 16 bytes long; received {bytes} byte
Error message
The byte string must be 16 bytes long; received {bytes} bytes What it means
Nonstandard\Fields is the lenient fields implementation used by Nonstandard\UuidBuilder (the builder behind Ulid and other non-RFC layouts). It performs only one structural check: the byte string must be exactly 16 bytes (128 bits); variant and version are not validated. Any other length throws InvalidArgumentException.
Source
Thrown at src/Nonstandard/Fields.php:56
*
* Internally, this class represents the fields together as a 16-byte binary string.
*
* @immutable
*/
final class Fields implements FieldsInterface
{
use SerializableFieldsTrait;
use VariantTrait;
/**
* @param string $bytes A 16-byte binary string representation of a UUID
*
* @throws InvalidArgumentException if the byte string is not exactly 16 bytes
*/
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',
);
}
}
public function getBytes(): string
{
return $this->bytes;
}
public function getClockSeq(): Hexadecimal
{
$clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;
return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT));
}
public function getClockSeqHiAndReserved(): HexadecimalView on GitHub (pinned to da5b521600)
Solutions
- Verify strlen($bytes) === 16 before building; convert with exactly 32 hex chars
- Use Ulid::fromString()/fromBytes() for ULID parsing so earlier validation gives clearer errors
- Add a length assertion at your storage boundary (e.g. VARBINARY(16) columns)
Example fix
// before
$ulid = \Ramsey\Uuid\Nonstandard\Ulid::fromBytes($value);
// after
if (strlen($value) !== 16) {
throw new InvalidArgumentException('ULID bytes must be 16, got ' . strlen($value));
}
$ulid = \Ramsey\Uuid\Nonstandard\Ulid::fromBytes($value); Defensive patterns
Strategy: validation
Validate before calling
if (strlen($bytes) !== 16) {
throw new InvalidArgumentException('Expected 16 bytes, got ' . strlen($bytes));
}
$ulid = \Ramsey\Uuid\Nonstandard\Ulid::fromBytes($bytes); Type guard
function isSixteenByteString(string $bytes): bool
{
return strlen($bytes) === 16;
} Try / catch
try {
$ulid = \Ramsey\Uuid\Nonstandard\Ulid::fromBytes($bytes);
} catch (\Ramsey\Uuid\Exception\InvalidArgumentException $e) {
// length or upstream parse failure; re-fetch or reject the payload
} Prevention
- Assert 16-byte length right after reading binary from storage
- Validate hex strings are exactly 32 chars before hex2bin()
- Use fixed-size binary columns for ULIDs
When it happens
Trigger: Calling Nonstandard\UuidBuilder::build($codec, $bytes) (used by Ulid::fromString()/fromBytes internally) or constructing Nonstandard\Fields directly with a byte string whose length differs from 16 — e.g. hex2bin('abc') on odd-length hex, a truncated ULID byte payload, or appending a prefix/suffix to the binary form.
Common situations: Custom codecs or builders for ULID/nonstandard identifiers; binary round-trips through columns or queues that truncate; passing hex strings where the API expects raw bytes.
Related errors
- The byte string must be 16 bytes long; received {bytes} byte
- The byte string must be 16 bytes long; received {} bytes
- The byte string received does not conform to the RFC 9562 (f
- Could not find a suitable builder for the provided codec and
- Expected version 1 (time-based) UUID
AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21).
Data as JSON: /api/errors/322b8c5411292401.
Report an issue: GitHub.