pentaho/pentaho-kettle · error · KettleFileException
TextFileInput.Log.SingleLineFound
TextFileInput.Log.SingleLineFound
Error message
TextFileInput.Log.SingleLineFound
What it means
TextFileInputUtils.getLine() throws KettleFileException 'TextFileInput.Log.SingleLineFound' when, after reading a carriage return (old Mac-style \r line ending), the next character is neither a return nor a linefeed. Since the reader treats \r as a complete line terminator, a character was consumed from the following line, meaning the file does not use DOS (\r\n) or Unix (\n) line endings as configured.
Solutions
- Convert the file to Unix (\n) or DOS (\r\n) line endings: dos2unix, or 'tr \\r \\n < in > out' for CR-only files.
- Set the file's format/encoding type in the Content tab to match the actual line-ending style.
- Preprocess the file in a prior step (e.g. a UDJC or shell script) to normalize line endings.
- Check for stray \r characters inside quoted fields and strip them.
- Re-transfer the file in binary mode to avoid incomplete newline mangling.
Example fix
// before: CR-only file fed directly to the step # file uses \r endings, step expects \r\n // after: normalize line endings first tr '\r' '\n' < input.mac.txt > input.unix.txt
Defensive patterns
Strategy: fallback
Validate before calling
// detect CR-only files before processing
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(path))) {
int b, cr = 0, lf = 0, crlf = 0, prev = -1;
while ((b = in.read()) != -1) {
if (b == '\r') { cr++; if (prev == '\r') {} }
if (b == '\n') { lf++; if (prev == '\r') crlf++; }
prev = b;
}
if (cr > 0 && crlf == 0 && lf == 0) throw new KettleFileException("CR-only line endings detected; convert the file first");
} Type guard
// a line is safe to parse only if it ends with \n or \r\n, never a bare \r mid-stream
boolean isWellFormedLineEnding(String raw) { return !raw.contains("\r\n\r") && raw.chars().filter(c -> c=='\r').count() <= raw.chars().filter(c -> c=='\n').count(); } Try / catch
try {
String line = TextFileInputUtils.getLine(log, reader, encodingType, ...");
} catch (KettleFileException e) {
if (String.valueOf(e.getMessage()).contains("SingleLineFound")) {
// normalize line endings and restart the read
} else throw e;
} Prevention
- Normalize files to \n or \r\n with dos2unix before ingestion.
- Transfer files in binary mode to avoid line-ending mangling.
- Set the step's file format (DOS/Unix/Mixed) to match the source.
- Reject or preprocess legacy CR-only files at intake.
When it happens
Trigger: Reading a file via getLine()/sline() that contains bare \r characters (classic Mac line endings, or stray \r inside data) while the encoding type expects \r to end a line followed by \n; getLine() pulls the first char of the next line and raises the error.
Common situations: Files created on classic Mac OS or exported by legacy tools using CR-only endings; binary or mixed-format data accidentally fed to the text input step; files transferred between systems with partial line-ending conversion.
Related errors
- TextFileInput.Log.SingleLineFound
- ChangeFileEncoding.Error.CreatingFile
- ChangeFileEncoding.Error.ParentFolderNotExist
- ChangeFileEncoding.Error.SourceFileNotAFile
- ChangeFileEncoding.Error.SourceFileNotExists
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/4ac093c5fc7541df.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/fileinput/text/TextFileInputUtils.java:366
public static final String getLine( LogChannelInterface log, BufferedInputStreamReader reader, EncodingType encodingType,
int formatNr, StringBuilder line ) throws KettleFileException {
int c = 0;
line.setLength( 0 );
try {
switch( formatNr ) {
case TextFileInputMeta.FILE_FORMAT_DOS:
while ( c >= 0 ) {
c = reader.read();
if ( encodingType.isReturn( c ) || encodingType.isLinefeed( c ) ) {
c = reader.read(); // skip \n and \r
if ( !encodingType.isReturn( c ) && !encodingType.isLinefeed( c ) ) {
// make sure its really a linefeed or cariage return
// raise an error this is not a DOS file
// so we have pulled a character from the next line
throw new KettleFileException( BaseMessages.getString( PKG, "TextFileInput.Log.SingleLineFound" ) );
}
return line.toString();
}
if ( c >= 0 ) {
line.append( (char) c );
}
}
break;
case TextFileInputMeta.FILE_FORMAT_UNIX:
while ( c >= 0 ) {
c = reader.read();
if ( encodingType.isLinefeed( c ) || encodingType.isReturn( c ) ) {
return line.toString();
}
if ( c >= 0 ) {
line.append( (char) c );
}View on GitHub (pinned to f3058517a1)