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
- Repair the data so every value has even length.
- Normalize before the value reaches Hibernate: left-pad with '0' when length is odd.
- 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
- Left-pad odd-length hex before assignment.
- Use varbinary columns + byte[] mappings instead of hex text.
- Reject non-hex characters at the ingest boundary.
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
- Unexpected PostgreSQL lock_timeout format: {}
- Could not find root
- Cannot parse given string into array of strings. First and l
- Cannot parse given string into array of strings. Outside of
- Cannot parse given string into array of Booleans. First and
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c3783af8f4553456.
Report an issue: GitHub.