pentaho/pentaho-kettle · error · KettleException
java.lang.NullPointerException (wrapped; row too short for…
Error message
java.lang.NullPointerException (wrapped; row too short for index)
What it means
In CsvInputAwareHelper.getStringFromRow, when failOnParseError is true and the requested index exceeds the row's length, a raw NullPointerException is thrown wrapped in a KettleException. The empty NPE gives no message, but the semantic is 'row too short for the requested field index'.
Solutions
- Remove/pre-filter blank or truncated lines from the input file
- Check the step's header-line and field-count settings against the actual file
- Enable error handling for the step so short rows go to an error stream instead of failing
- Read the KettleException's cause (NullPointerException) as the signal that index exceeded row length
Example fix
// before file.csv last line: 'a,b' // step defines 3 fields -> row too short // after ensure every data line has all fields: 'a,b,' or filter empty lines with a 'Filter rows' step on field1 <> ''
Defensive patterns
Strategy: validation
Validate before calling
// check each line's column count before processing
String[] cols = line.split(",", -1);
if (cols.length < expectedFieldCount) skipBlankLine(line); Type guard
boolean rowHasField(Object[] row, int index) {
return row != null && row.length > index;
} Try / catch
try { string = helper.getStringFromRow(row, index, false); }
catch (KettleException e) { if (e.getCause() instanceof NullPointerException) logError("Row too short: " + row.length); throw e; } Prevention
- Strip trailing blank lines from CSV files
- Ensure every row has all delimiters (trailing commas for empty fields)
- Set correct header-line count in the step
When it happens
Trigger: row.length <= index and failOnParseError is true — the physical row has fewer columns than the defined field count (e.g. trailing empty line or truncated record).
Common situations: CSV files with blank trailing lines, ragged rows with missing trailing delimiters, wrong 'N of header lines' settings, or files where the last line lacks a newline and is mis-split.
Related errors
- CsvInput.Exception.ErrorPreparingParallelRun
- e.getMessage() (first conversion cause, no own message)
- exc (wraps parse exception, no own message)
- AccessInputMeta.Exception.ErrorSavingToRepository
- AccessInputMeta.Exception.FileDoesNotExist
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a10775fc81b0b112.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/common/CsvInputAwareHelper.java:200
} catch ( final Exception e ) {
exc = e;
}
// if 'failOnParseError' is true, and we caught an exception, we either re-throw the exception, or wrap its as a
// KettleException, if it isn't one already
if ( failOnParseError ) {
if ( exc instanceof KettleException ) {
throw (KettleException) exc;
} else if ( exc != null ) {
throw new KettleException( exc );
}
}
// if 'failOnParseError' is false, or there is no exception otherwise, we get the string value straight from the row
// object
if ( string == null ) {
if ( ( row.length <= index ) && failOnParseError ) {
throw new KettleException( new NullPointerException() );
}
string = row.length <= index || row[ index ] == null ? null : row[ index ].toString();
}
return string;
}
/**
* Creates a buffered input stream reader for the given CSV input metadata and input stream.
*
* @param meta the CSV input metadata
* @param inputStream the input stream to read from
* @return a BufferedInputStreamReader for reading the CSV file
*/
default BufferedInputStreamReader getBufferedReader( final TransMeta transMeta, final CsvInputAwareMeta meta,
final InputStream inputStream ) {
return new BufferedInputStreamReader( getReader( transMeta, meta, inputStream ) );
}View on GitHub (pinned to f3058517a1)