pentaho/pentaho-kettle · error · KettleFileException

CsvInput.Exception.CreateFieldMappingError

Error message

CsvInput.Exception.CreateFieldMappingError

What it means

readFieldNamesFromFile opens the CSV file and parses the header line to build the field mapping. Any IOException during this process (file unreadable mid-read, decoding failure, stream error) is wrapped in a KettleFileException carrying the 'CreateFieldMappingError' message, indicating the step could not derive field names from the file's first line.

Solutions

  1. Re-check the file is accessible and not locked by another process.
  2. Verify the encoding configured in the step matches the file's actual charset.
  3. Re-select/refresh the file path in the dialog and retry 'Get fields'.
  4. Open the file with a plain editor to confirm it is a valid, non-corrupt CSV.

Example fix

// before: encoding mismatch
Encoding = "UTF-16"
// after
Encoding = "UTF-8"
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the file's header is readable with the configured encoding before parsing
byte[] head = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(filename));
String header = new String(head, 0, Math.min(head.length, 4096), java.nio.charset.Charset.forName(encoding));
if (header.isEmpty()) throw new IllegalStateException("Empty or undecodable header: " + filename);

Try / catch

try { ... } catch (KettleFileException e) {
  logError("Could not read header from CSV: " + e.getCause(), e);
  setErrors(1);
}

Prevention

When it happens

Trigger: IOException raised while reading the first line(s) of the CSV file in readFieldNamesFromFile — e.g. the file is deleted/locked after being opened, encoding issues causing a read failure, or the underlying channel errors out during header parse. Called via the static fieldNames() path / 'Get fields' in the dialog.

Common situations: Clicking 'Get fields from header row' in the step dialog against a locked, moved, or undecodable file; wrong charset configured so the byte stream cannot be decoded; file truncated or on a flaky network share.

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/a0272716ab768851. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/csvinput/CsvInput.java:477

      InputStreamReader reader = null;
      if ( Utils.isEmpty( realEncoding ) ) {
        reader = new InputStreamReader( inputStream );
      } else {
        reader = new InputStreamReader( inputStream, realEncoding );
      }
      EncodingType encodingType = EncodingType.guessEncodingType( reader.getEncoding() );
      String line =
          TextFileInput.getLine( log, reader, encodingType, TextFileInputMeta.FILE_FORMAT_UNIX, new StringBuilder(
              1000 ) );
      String[] fieldNames =
          CsvInput.guessStringsFromLine( log, line, delimiter, enclosure, csvInputMeta.getEscapeCharacter() );
      if ( !Utils.isEmpty( csvInputMeta.getEnclosure() ) ) {
        removeEnclosure( fieldNames, csvInputMeta.getEnclosure() );
      }
      trimFieldNames( fieldNames );
      return fieldNames;
    } catch ( IOException e ) {
      throw new KettleFileException( BaseMessages.getString( PKG, "CsvInput.Exception.CreateFieldMappingError" ), e );
    }
  }

  static String[] fieldNames( CsvInputMeta csvInputMeta ) {
    TextFileInputField[] fields = csvInputMeta.getInputFields();
    String[] fieldNames = new String[fields.length];
    for ( int i = 0; i < fields.length; i++ ) {
      // We need to sanitize field names because existing ktr files may contain field names with leading BOM
      fieldNames[i] = EncodingType.removeBOMIfPresent( fields[i].getName() );
    }
    return fieldNames;
  }

  static void trimFieldNames( String[] strings ) {
    if ( strings != null ) {
      for ( int i = 0; i < strings.length; i++ ) {
        strings[ i ] = strings[ i ].trim();
      }

View on GitHub (pinned to f3058517a1)