{"record":{"id":"2c26a2de0484f28c","repo":"hibernate/hibernate-orm","slug":"start-position-start-cannot-exceed-overall-cl","errorCode":null,"errorMessage":"Start position [${start}] cannot exceed overall CLOB length [${length}]","messagePattern":"Start position \\[(.+?)\\] cannot exceed overall CLOB length \\[(.+?)\\]","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/ClobProxy.java","lineNumber":129,"sourceCode":"\t}\n\n\t@Override\n\tpublic Writer setCharacterStream(long pos) {\n\t\tthrow notSupported();\n\t}\n\n\t@Override\n\tpublic void truncate(long len) throws SQLException {\n\t\tthrow notSupported();\n\t}\n\n\t@Override\n\tpublic String getSubString(long start, int length) throws SQLException {\n\t\tif ( start < 1 ) {\n\t\t\tthrow new SQLException( \"Start position 1-based; must be 1 or more.\" );\n\t\t}\n\t\tif ( start > length() + 1 ) {\n\t\t\tthrow new SQLException( \"Start position [\" + start + \"] cannot exceed overall CLOB length [\" + length() + \"]\" );\n\t\t}\n\t\tif ( length < 0 ) {\n\t\t\tthrow new SQLException( \"Length must be great-than-or-equal to zero.\" );\n\t\t}\n\t\tfinal String string = characterStream.asString();\n\t\tfinal long endIndex = Math.min( start + length - 1, string.length() );\n\t\treturn string.substring( (int) start - 1, (int) endIndex );\n\t}\n\n\t@Override\n\tpublic Reader getCharacterStream(long start, long length) throws SQLException {\n\t\tif ( start < 1 ) {\n\t\t\tthrow new SQLException( \"Start position 1-based; must be 1 or more.\" );\n\t\t}\n\t\tif ( start > length() + 1 ) {\n\t\t\tthrow new SQLException( \"Start position [\" + start + \"] cannot exceed overall CLOB length [\" + length() + \"]\" );\n\t\t}\n\t\tif ( length > Integer.MAX_VALUE ) {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/ClobProxy.java#L111-L147","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nString part = clob.getSubString(start, 100); // start may be past the end\n\n// after\nlong maxStart = clob.length() + 1;\nString part = start <= maxStart ? clob.getSubString(start, 100) : \"\";","handlingStrategy":"validation","validationCode":"static String window(java.sql.Clob clob, long start, int length) throws SQLException {\n    long maxStart = clob.length() + 1;              // start == maxStart yields \"\"\n    if (start < 1) throw new IllegalArgumentException(\"start must be >= 1\");\n    if (start > maxStart) return \"\";                // fully past the end: empty\n    return clob.getSubString(start, length);\n}","typeGuard":null,"tryCatchPattern":"try {\n    s = clob.getSubString(start, length);\n} catch (SQLException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"cannot exceed overall\")) {\n        s = \"\";                                     // past the end: empty result\n    } else {\n        throw e;\n    }\n}","preventionTips":["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"],"tags":["hibernate","jdbc","clob","lob","out-of-range","off-by-one","sql-exception"],"backgroundTag":"jdbc-lob-position-exceeds-length","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}