pentaho/pentaho-kettle · error · KettleFileException
TextFileInput.Log.SingleLineFound
Error message
TextFileInput.Log.SingleLineFound
What it means
When parsing records that can span multiple lines (e.g. enclosed newlines), after consuming what looks like an end-of-line the parser re-checks for another line feed to distinguish single vs double line endings. If a single line feed is found where the configured format (DOS/Unix double endings context) requires a proper record terminator, a KettleFileException 'SingleLineFound' is thrown because the record structure does not match the configured format.
Solutions
- Set 'File format' to 'Mixed' in the step dialog if the file contains inconsistent line endings.
- Normalize the file's line endings (dos2unix / unix2dos) to match the configured format.
- Verify the enclosure and terminator settings; check the raw bytes around the failing line with a hex editor.
- Re-save the source file with a single consistent newline style.
Example fix
// before fileFormat = "DOS" // file has mixed LF/CRLF // after fileFormat = "Mixed"
Defensive patterns
Strategy: validation
Validate before calling
// detect mixed line endings before choosing the file format
byte[] bytes = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(filename));
boolean hasCrlf = new String(bytes).contains("\r\n");
boolean hasLoneLf = new String(bytes).replaceAll("\r\n", "").contains("\n");
if (hasCrlf && hasLoneLf) useFileFormat = "Mixed"; Try / catch
try { ... } catch (KettleFileException e) {
logError("Line-ending structure mismatch; switch File format to Mixed or normalize the file", e);
setErrors(1);
} Prevention
- Scan files for mixed CRLF/LF before choosing the File format
- Use 'Mixed' when files come from multiple sources/OSes
- Normalize line endings with dos2unix/unix2dos upstream
- Inspect suspicious lines in a hex editor
When it happens
Trigger: File format is set to DOS or Unix (not Mixed) and the buffer logic in readOneRow encounters an end-of-line where, after moving the end-buffer pointer, data.newLineFound() is false — i.e. an odd/lonely line ending inconsistent with the configured multi-line record format.
Common situations: Mixing CRLF and LF line endings in one file while format is set to DOS; files edited on different OSes; wrong 'File format' selected in the step dialog for the actual file; stray lone CR/LF characters inside the data.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- TextFileInput.Log.SingleLineFound
- A deadlock was detected between steps
- AbsSecurityManager.ERROR_0003_UNABLE_TO_ACCESS_ROLE_BINDING_WEBSVC
- AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE
- AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/aface693bdcccc17.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/csvinput/CsvInput.java:785
// empty column at the end of the row (see the Jira case for details)
if ( ( !newLineFound && outputIndex < data.fieldsMapping.size() ) || ( newLineFound && doubleLineEnd ) ) {
int i = 0;
while ( ( !data.newLineFound() && ( i < data.delimiter.length ) ) ) {
data.moveEndBufferPointer();
i++;
}
switch ( meta.getFileFormatTypeNr() ) {
case TextFileInputMeta.FILE_FORMAT_DOS:
if ( data.newLineFound() ) {
if ( doubleLineEnd == true ) {
data.moveEndBufferPointerXTimes( data.encodingType.getLength() );
} else {
//Re-check for a new Line
data.moveEndBufferPointerXTimes( data.encodingType.getLength() );
if ( !data.newLineFound() ) {
throw new KettleFileException( BaseMessages.getString( PKG, "TextFileInput.Log.SingleLineFound" ) );
}
}
}
break;
case TextFileInputMeta.FILE_FORMAT_MIXED:
if ( data.isCarriageReturn() || doubleLineEnd ) {
data.moveEndBufferPointerXTimes( data.encodingType.getLength() );
}
break;
}
}
data.setStartBuffer( data.getEndBuffer() );
}
// See if we reached the end of the line.
// If not, we need to skip the remaining items on the line until the next newline...
//View on GitHub (pinned to f3058517a1)