hibernate/hibernate-orm · error · SQLException
Start position [${start}] cannot exceed overall CLOB length
Error message
Start position [${start}] cannot exceed overall CLOB length [${length}] What it means
ClobProxy.getSubString(long start, int length) checks start against length() + 1. JDBC allows start == length() + 1 (one past the last character, returning an empty string), but anything larger is invalid and throws this SQLException with the actual start and the overall CLOB length interpolated into the message.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/ClobProxy.java:129
}
@Override
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 ) {View on GitHub (pinned to fad1729dce)
Solutions
- Guard the call: if (start <= clob.length() + 1) before reading
- Terminate windowing loops when the previous read returns fewer characters than requested
- For empty Clobs skip reading altogether
Example fix
// before String part = clob.getSubString(start, 100); // start may be past the end // after long maxStart = clob.length() + 1; String part = start <= maxStart ? clob.getSubString(start, 100) : "";
Defensive patterns
Strategy: validation
Validate before calling
static String window(java.sql.Clob clob, long start, int length) throws SQLException {
long maxStart = clob.length() + 1; // start == maxStart yields ""
if (start < 1) throw new IllegalArgumentException("start must be >= 1");
if (start > maxStart) return ""; // fully past the end: empty
return clob.getSubString(start, length);
} Try / catch
try {
s = clob.getSubString(start, length);
} catch (SQLException e) {
if (e.getMessage() != null && e.getMessage().contains("cannot exceed overall")) {
s = ""; // past the end: empty result
} else {
throw e;
}
} Prevention
- Compare start against clob.length() + 1 before every positioned read
- Stop pagination when a page comes back shorter than the page size
- Handle empty Clobs before entering the read path
When it happens
Trigger: Calling getSubString(start, n) with start > clob.length() + 1 (e.g. 60 on a 50-char Clob); a windowing loop whose cursor advances past the end; using a stale length after the Clob content shrank.
Common situations: Text pagination loops without an end bound; empty Clobs (length 0) where any start > 1 fails; off-by-one ports of String.substring where end index is fed as start.
Related errors
- Start position [<start>] cannot exceed overall CLOB length [
- Start position 1-based; must be 1 or more.
- Start position 1-based; must be 1 or more.
- Length must be great-than-or-equal to zero.
- 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/2c26a2de0484f28c.
Report an issue: GitHub.