pentaho/pentaho-kettle · error · KettleException

MailConnection.Error.FolderNotFound

Error message

MailConnection.Error.FolderNotFound

What it means

Thrown from prepareMboxDestinationPath() when the parent directory of the resolved MBOX destination path does not exist and createFolder is false. It uses key MailConnection.Error.FolderNotFound with the requested folder name. The method refuses to auto-create directories unless the caller opted in.

Solutions

  1. Pass createFolder=true to setDestinationFolder so the parent directory is created via mkdirs().
  2. Pre-create the parent directory on the filesystem (mkdir -p).
  3. Fix the configured folder path to point at an existing directory.

Example fix

// before
connection.setDestinationFolder("/data/mail/archive/2024", false); // parent missing
// after
connection.setDestinationFolder("/data/mail/archive/2024", true);
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(resolvedPath);
if (f.getParentFile() != null && !f.getParentFile().exists() && !createFolder) { throw new IllegalArgumentException("Parent directory missing and createFolder=false"); }

Try / catch

try { connection.setDestinationFolder(path, true); } catch (KettleException e) { logError("Folder not found: " + e.getMessage(), e); }

Prevention

When it happens

Trigger: Calling setDestinationFolder(foldername, createFolder=false) with MBOX protocol where the destination path's parent directory (e.g. /data/mail/INBOX) does not exist on disk.

Common situations: Destination mbox folder moved or deleted between runs; environment migration where the mail directory was not recreated; typo in the configured path; create/dry-run mode left unchecked.

Related errors


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

Appendix: source

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

    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, ERROR_SET_DESTINATION, foldername ), e );
    }
  }

  private String prepareMboxDestinationPath( String foldername, boolean createFolder ) throws KettleException {
    String resolvedPath = resolveMboxFolderPath( foldername );
    File destinationFile = new File( resolvedPath );
    File parentDirectory = destinationFile.getParentFile();
    if ( parentDirectory == null ) {
      return resolvedPath;
    }

    if ( parentDirectory.exists() && !parentDirectory.isDirectory() ) {
      throw new KettleException( BaseMessages.getString( PKG, ERROR_CREATE_FOLDER, resolvedPath ) );
    }
    if ( !parentDirectory.exists() ) {
      if ( !createFolder ) {
        throw new KettleException( BaseMessages.getString( PKG, ERROR_FOLDER_NOT_FOUND, foldername ) );
      }
      if ( !parentDirectory.mkdirs() ) {
        throw new KettleException( BaseMessages.getString( PKG, ERROR_CREATE_FOLDER, resolvedPath ) );
      }
    }
    return resolvedPath;
  }

  private Folder getOrCreateImapDestinationFolder( String foldername, boolean createFolder )
    throws MessagingException, KettleException {
    String[] folderparts = foldername.split( "/" );
    Folder destinationFolder = this.getStore().getDefaultFolder();
    for ( String folderPart : folderparts ) {
      destinationFolder = destinationFolder.getFolder( folderPart );
      if ( destinationFolder.exists() ) {
        continue;
      }
      if ( !createFolder ) {

View on GitHub (pinned to f3058517a1)