pentaho/pentaho-kettle · error · KettleDatabaseException
MySQLDatabaseMeta.Exception.LegacyColumnNameException
MySQLDatabaseMeta.Exception.LegacyColumnNameException
Error message
%s: %s (localized message + e.getMessage())
What it means
Wraps any Exception from reading the column name/label (getColumnLabel or getColumnName, chosen by driver major version > 3) in MySQLDatabaseMeta.getLegacyColumnName. The message combines the localized 'LegacyColumnNameException' text with the underlying exception's message, keeping the cause chained.
Solutions
- Validate index against rsMetaData.getColumnCount() (1-based) before the call
- Keep the ResultSet open until all columns are processed
- Inspect the chained cause in the KettleDatabaseException for the driver-level error
Example fix
// before
for (int i = 0; i < rsMetaData.getColumnCount(); i++) {
String name = meta.getLegacyColumnName(dbMetaData, rsMetaData, i);
}
// after
for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
String name = meta.getLegacyColumnName(dbMetaData, rsMetaData, i);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (index < 1 || index > rsMetaData.getColumnCount()) throw new IllegalArgumentException("Column index " + index + " out of 1.." + rsMetaData.getColumnCount()); Type guard
function isValidColumnIndex(ResultSetMetaData md, int i) { try { return i >= 1 && i <= md.getColumnCount(); } catch (SQLException e) { return false; } } Try / catch
try {
String name = mysqlMeta.getLegacyColumnName(dbMetaData, rsMetaData, index);
} catch (KettleDatabaseException e) {
Throwable cause = e.getCause(); // underlying SQLException from getColumnLabel/getColumnName
log.error("Failed to read MySQL column name for index " + index + ": " + (cause != null ? cause.getMessage() : e.getMessage()), e);
} Prevention
- Use 1-based indices bounded by getColumnCount()
- Keep the ResultSet open during metadata reads
- Log the chained cause to identify driver version-specific issues
When it happens
Trigger: ResultSetMetaData.getColumnLabel(index) or getColumnName(index) throws — typically an invalid index (out of 1..columnCount range) or a closed/stale ResultSet.
Common situations: Off-by-one column loops; accessing metadata after closing the statement; MySQL Connector/J errors during metadata retrieval.
Related errors
- MySQLDatabaseMeta.Exception.LegacyColumnNameNoDBMetaDataException
- MySQLDatabaseMeta.Exception.LegacyColumnNameException
- Cannot fetch driver metadata for
- Database.Exception.EmptyConnectionError
- Database.Exception.UnableToGetMetadata
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a180fe6877d3614c.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/MySQLDatabaseMeta.java:535
* @param dbMetaData
* @param rsMetaData
* @param index
* @return The column label if version is greater than 3 or the column name if version is lower or equal to 3.
* @throws KettleDatabaseException
*/
public String getLegacyColumnName( DatabaseMetaData dbMetaData, ResultSetMetaData rsMetaData, int index ) throws KettleDatabaseException {
if ( dbMetaData == null ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "MySQLDatabaseMeta.Exception.LegacyColumnNameNoDBMetaDataException" ) );
}
if ( rsMetaData == null ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "MySQLDatabaseMeta.Exception.LegacyColumnNameNoRSMetaDataException" ) );
}
try {
return dbMetaData.getDriverMajorVersion() > 3 ? rsMetaData.getColumnLabel( index ) : rsMetaData.getColumnName( index );
} catch ( Exception e ) {
throw new KettleDatabaseException( String.format( "%s: %s", BaseMessages.getString( PKG, "MySQLDatabaseMeta.Exception.LegacyColumnNameException" ), e.getMessage() ), e );
}
}
}
View on GitHub (pinned to f3058517a1)