pentaho/pentaho-kettle · error · KettleException

Unable to convert file '

Error message

Unable to convert file '

What it means

JobEntryDosToUnix wraps any Exception thrown while converting a file's line endings (DOS CRLF to Unix LF) in a KettleException with the message 'Unable to convert file <path>'. The underlying cause (e.g. an IOException while reading/writing, or an error while adding the file to the result filenames list) is attached as the cause. It signals the dos-to-unix job entry failed to process one specific file and the entry's execute() aborts.

Solutions

  1. Inspect the chained cause exception (e.getCause()) to find the real I/O failure and its file path.
  2. Verify the file exists, is a regular file, and the Pentaho process user has read/write permission on it.
  3. Check disk space and that the file is not locked/open exclusively by another process.
  4. Correct the file/folder/wildcard settings in the job entry so only valid target files are selected.
  5. If 'add file to result' is enabled, ensure the result filenames configuration is valid.

Example fix

// before
jobEntry.execute(prevResult, 0); // throws KettleException 'Unable to convert file ...'
// after
File f = new File(path);
if (f.isFile() && f.canRead() && f.canWrite()) {
  jobEntry.execute(prevResult, 0);
} else {
  logError("Skipping non-writable file: " + path);
}
Defensive patterns

Strategy: try-catch

Validate before calling

File f = new File(path);
if (!f.isFile() || !f.canRead() || !f.canWrite()) {
  throw new IllegalStateException("File not readable/writable: " + path);
}
if (f.getUsableSpace() < f.length() * 2) {
  throw new IllegalStateException("Insufficient disk space for conversion");
}

Try / catch

try {
  result = dosToUnixEntry.execute(prevResult, 0);
} catch (KettleException e) {
  Throwable cause = e.getCause();
  logError("DosToUnix failed for file: " + cause.getMessage(), e);
  result.setResult(false);
}

Prevention

When it happens

Trigger: Calling execute() on a JobEntryDosToUnix whose configured file/folder/wildcard selection matches a file that cannot be read, written, or whose addFileToResultFilenames call throws; the try block around convert() catches Exception and rethrows at this line.

Common situations: File does not exist or is locked by another process; insufficient read/write permissions on the target file or directory; the file is a directory or a special file; disk full while writing the converted file; result-filename configuration referencing ADD_ALL_FILENAMES/ADD_PROCESSED_FILES_ONLY with an inaccessible result file.

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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/dostounix/JobEntryDosToUnix.java:696

        updateBadFormed();
        if ( resultfilenames.equals( ADD_ALL_FILENAMES ) || resultfilenames.equals( ADD_ERROR_FILES_ONLY ) ) {
          addFileToResultFilenames( file, result, parentJob );
        }
      } else {
        if ( isDetailed() ) {
          logDetailed( "---------------------------" );
          logDetailed( BaseMessages.getString( PKG, "JobDosToUnix.Error.FileConverted", file, convertToUnix
            ? "UNIX" : "DOS" ) );
        }
        // Update processed files number
        updateProcessedFormed();
        if ( resultfilenames.equals( ADD_ALL_FILENAMES ) || resultfilenames.equals( ADD_PROCESSED_FILES_ONLY ) ) {
          addFileToResultFilenames( file, result, parentJob );
        }
      }

    } catch ( Exception e ) {
      throw new KettleException( "Unable to convert file '" + file.toString() + "'", e );
    }
    return retval;
  }

  private void updateProcessedFormed() {
    nrProcessedFiles++;
  }

  private void updateBadFormed() {
    nrErrorFiles++;
    updateAllErrors();
  }

  private void addFileToResultFilenames( FileObject fileaddentry, Result result, Job parentJob ) {
    try {
      ResultFile resultFile =
        new ResultFile( ResultFile.FILE_TYPE_GENERAL, fileaddentry, parentJob.getJobname(), toString() );
      result.getResultFiles().put( resultFile.getFile().toString(), resultFile );

View on GitHub (pinned to f3058517a1)