pentaho/pentaho-kettle · error · KettleException

JobGetMailsFromPOP.Error.NotAFolderNot

Error message

JobGetMailsFromPOP.Error.NotAFolderNot

What it means

createOutputDirectory() resolves the output folder via KettleVFS and checks folder.exists(); if the path exists but its VFS FileType is not FileType.FOLDER (e.g. a regular file or symlink to a file), the entry throws this KettleException with the folder name as a message parameter. It prevents attempting folder operations (createFolder, message writes) on a non-directory path.

Solutions

  1. Remove or rename the file that occupies the configured output path, then let the entry create/verify the directory.
  2. Point the 'Output directory' field at a directory path (trailing path segment, not a filename).
  3. Check the resolved variable value (log it or test in a Get Variable step) to make sure it expands to the intended directory.

Example fix

// before
output directory = /data/mails.bak   (a file)
// after
output directory = /data/mails      (directory, file moved aside)
Defensive patterns

Strategy: validation

Validate before calling

File out = new File(environmentSubstitute(getOutputFolder()));
if (out.exists() && !out.isDirectory()) {
  throw new IllegalArgumentException("Output path exists but is not a directory: " + out);
}

Try / catch

try { executeJobEntry(); } catch (KettleException e) {
  if (e.getMessage().contains("NotAFolderNot")) {
    logError("Configured output path is a file, not a directory: " + e.getMessage());
  } else { throw e; }
}

Prevention

When it happens

Trigger: createOutputDirectory(FOLDER_OUTPUT) where the resolved folderName exists on disk/VFS as a file, not a directory.

Common situations: User points the output directory at an existing file (e.g. a zip or log file path); a variable expansion produced a filename rather than a directory; a previous run created a file at the intended folder path.

Related errors


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

Appendix: source

Thrown at plugins/email-messages/impl/src/main/java/org/pentaho/di/job/entries/getpop/JobEntryGetPOP.java:1590

        } else {
          folderName = getRealOutputDirectory();
        }
        break;
    }
    if ( Utils.isEmpty( folderName ) ) {
      switch ( folderType ) {
        case JobEntryGetPOP.FOLDER_OUTPUT:
          throw new KettleException( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Error.OutputFolderEmpty" ) );
        case JobEntryGetPOP.FOLDER_ATTACHMENTS:
          throw new KettleException( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Error.AttachmentFolderEmpty" ) );
      }
    }
    FileObject folder = KettleVFS.getInstance( parentJobMeta.getBowl() ).getFileObject( folderName, this );
    if ( folder.exists() ) {
      if ( folder.getType() != FileType.FOLDER ) {
        switch ( folderType ) {
          case JobEntryGetPOP.FOLDER_OUTPUT:
            throw new KettleException( BaseMessages.getString(
              PKG, "JobGetMailsFromPOP.Error.NotAFolderNot", folderName ) );
          case JobEntryGetPOP.FOLDER_ATTACHMENTS:
            throw new KettleException( BaseMessages.getString(
              PKG, "JobGetMailsFromPOP.Error.AttachmentFolderNotAFolder", folderName ) );
        }
      }
      if ( isDebug() ) {
        switch ( folderType ) {
          case JobEntryGetPOP.FOLDER_OUTPUT:
            logDebug( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Log.OutputFolderExists", folderName ) );
            break;
          case JobEntryGetPOP.FOLDER_ATTACHMENTS:
            logDebug( BaseMessages.getString( PKG, "JobGetMailsFromPOP.Log.AttachmentFolderExists", folderName ) );
            break;
        }
      }
    } else {
      if ( isCreateLocalFolder() ) {

View on GitHub (pinned to f3058517a1)