pentaho/pentaho-kettle · error · KettleFileException

TextFileInput.Log.SingleLineFound

TextFileInput.Log.SingleLineFound

Error message

TextFileInput.Log.SingleLineFound

What it means

TextFileInput.getLine() throws KettleFileException with this message when, after reading a carriage return (\r), the very next character is NOT a linefeed (\n). For a DOS/Windows (CRLF) file this would always be a \n, so finding any other character means the parser has consumed one character from the next line, corrupting line boundaries.

Solutions

  1. Normalize the input file's line endings to LF or CRLF consistently before feeding it to the step (e.g. dos2unix or an editor save-as with a fixed EOL style).
  2. Set the step's line-ending/encoding format explicitly (DOS/Unix) so it matches the actual file content instead of relying on detection.
  3. Pre-process the file to strip stray CR characters not followed by LF (sed -i 's/\r$//' or equivalent).
  4. If the data legitimately contains bare CRs, enclose fields properly or switch to a parser that tolerates them.

Example fix

// before: file has mixed CR and CRLF endings, step throws
// after: normalize line endings before the transformation
//   tr -d '\r' < input.txt > input.normalized.txt
// (or set Format to 'Unix' for LF-only files in the Text File Input dialog)
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check for bare CR not followed by LF before running the step
boolean hasBareCR = false;
try (BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset))) {
  int prev = -1, c;
  while ((c = r.read()) != -1) {
    if (prev == '\r' && c != '\n') { hasBareCR = true; break; }
    prev = c;
  }
}

Try / catch

try {
  row = textFileInput.getLine();
} catch (KettleFileException e) {
  // mixed line endings: normalize file and retry
  normalizeLineEndings(file);
  row = textFileInput.getLine();
}

Prevention

When it happens

Trigger: Reading a mixed-line-ending file where a \r is followed by a real character instead of \n (e.g. old Mac CR-only line endings embedded in a file being parsed as DOS, or a file with a stray \r in mid-text) while the encoding type treats \r\n as a pair.

Common situations: Files edited on different OSes (Unix LF + old Mac CR mixed), files transferred with partial newline conversion, data exports containing stray carriage returns inside quoted fields.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/4fac2202d991021a. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/textfileinput/TextFileInput.java:110

  }

  public static final String getLine( LogChannelInterface log, InputStreamReader 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)