hibernate/hibernate-orm · error · SQLException
Length must be great-than-or-equal to zero.
Error message
Length must be great-than-or-equal to zero.
What it means
ClobProxy.getSubString(long start, int length) rejects a negative length with this SQLException (note the typo 'great-than-or-equal' in the Hibernate message). Zero is a legal length, but a negative count is a caller bug and fails fast before the substring is computed.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/ClobProxy.java:132
public Writer setCharacterStream(long pos) {
throw notSupported();
}
@Override
public void truncate(long len) throws SQLException {
throw notSupported();
}
@Override
public String getSubString(long start, int length) throws SQLException {
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > length() + 1 ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + length() + "]" );
}
if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." );
}
final String string = characterStream.asString();
final long endIndex = Math.min( start + length - 1, string.length() );
return string.substring( (int) start - 1, (int) endIndex );
}
@Override
public Reader getCharacterStream(long start, long length) throws SQLException {
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( start > length() + 1 ) {
throw new SQLException( "Start position [" + start + "] cannot exceed overall CLOB length [" + length() + "]" );
}
if ( length > Integer.MAX_VALUE ) {
throw new SQLException( "Can't deal with Clobs larger than 'Integer.MAX_VALUE'" );
}
if ( length < 0 ) {View on GitHub (pinned to fad1729dce)
Solutions
- Pass length >= 0; use 0 to validate start without reading
- Clamp computed lengths: int len = Math.max(0, end - start)
- Check indexOf results for -1 before deriving lengths from them
Example fix
// before int idx = content.indexOf(marker); String s = clob.getSubString(1, idx); // idx == -1 throws // after int idx = content.indexOf(marker); String s = clob.getSubString(1, Math.max(0, idx));
Defensive patterns
Strategy: validation
Validate before calling
static String safeSubString(java.sql.Clob clob, long start, int length) throws SQLException {
if (start < 1) throw new IllegalArgumentException("start must be >= 1");
if (length < 0) length = 0; // negative means 'read nothing'
return clob.getSubString(start, length);
} Try / catch
try {
s = clob.getSubString(start, length);
} catch (SQLException e) {
if (e.getMessage() != null && e.getMessage().contains("Length must be")) {
s = ""; // degrade to empty string
} else {
throw e;
}
} Prevention
- Check indexOf results for -1 before deriving substring lengths
- Clamp all length arithmetic with Math.max(0, ...)
- Keep the message typo 'great-than-or-equal' in mind when matching text
When it happens
Trigger: Calling clob.getSubString(1, -1); computing length = end - start and passing it negative when end < start; forwarding a -1 from String.indexOf (not found) into getSubString.
Common situations: Sentinel -1 values from indexOf/lastIndexOf leaking into substring extraction; reversed or clamped index arithmetic; 'read rest' helpers with an uninitialized size.
Related errors
- Length must be greater than or equal to zero
- Length must be great-than-or-equal to zero.
- Start position 1-based; must be 1 or more.
- Start position [${start}] cannot exceed overall CLOB length
- Can't deal with Clobs larger than 'Integer.MAX_VALUE'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/612f20b052e338f0.
Report an issue: GitHub.