hibernate/hibernate-orm · error · IllegalArgumentException

The string is not a valid string representation of a binary

Error message

The string is not a valid string representation of a binary content.

What it means

ByteArrayJavaType.fromString decodes a Byte[] from the hex string produced by toString(), where every byte is exactly two hex digits. An input of odd length cannot be split into byte pairs and throws IllegalArgumentException('The string is not a valid string representation of a binary content.').

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteArrayJavaType.java:96

	@Override
	public String toString(Byte[] bytes) {
		final var string = new StringBuilder();
		for ( Byte aByte : bytes ) {
			final String hexStr = toHexString( toUnsignedInt( aByte ) );
			if ( hexStr.length() == 1 ) {
				string.append( '0' );
			}
			string.append( hexStr );
		}
		return string.toString();
	}
	@Override
	public Byte[] fromString(CharSequence string) {
		if ( string == null ) {
			return null;
		}
		if ( string.length() % 2 != 0 ) {
			throw new IllegalArgumentException( "The string is not a valid string representation of a binary content." );
		}
		final var bytes = new Byte[string.length() / 2];
		for ( int i = 0; i < bytes.length; i++ ) {
			final String hexStr = string.subSequence( i * 2, (i + 1) * 2 ).toString();
			bytes[i] = (byte) Integer.parseInt( hexStr, 16 );
		}
		return bytes;
	}

	@Override
	public <X> X unwrap(Byte[] value, Class<X> type, WrapperOptions options) {
		if ( value == null ) {
			return null;
		}
		if ( Byte[].class.isAssignableFrom( type ) ) {
			return type.cast( value );
		}
		if ( byte[].class.isAssignableFrom( type ) ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Repair the data so every value has even length.
  2. Normalize before the value reaches Hibernate: left-pad with '0' when length is odd.
  3. Prefer byte[] with a native varbinary mapping over hex-in-varchar columns.

Example fix

// before
String hex = readLegacyColumn(); // e.g. "A0F" (3 chars) -> IllegalArgumentException
Byte[] data = ByteArrayJavaType.INSTANCE.fromString(hex);

// after
String hex = readLegacyColumn();
if (hex.length() % 2 != 0) hex = "0" + hex; // "0A0F"
Byte[] data = ByteArrayJavaType.INSTANCE.fromString(hex);
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidHex(String s) {
    return s != null && s.length() % 2 == 0 && s.matches("[0-9a-fA-F]*");
}

Prevention

When it happens

Trigger: A hex string of odd length in the column bound to a Byte[] attribute; hex truncated by manual edits or an external import; values that lost a leading zero during concatenation or formatting.

Common situations: Data-migration truncation; ETL steps that strip leading zeros; hand-edited seed rows; third-party systems writing hex with variable padding.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/c3783af8f4553456. Report an issue: GitHub.