{"record":{"id":"53bcc6d280952918","repo":"pentaho/pentaho-kettle","slug":"mailconnection-error-savingattachedfiles","errorCode":null,"errorMessage":"MailConnection.Error.SavingAttachedFiles","messagePattern":"MailConnection\\.Error\\.SavingAttachedFiles","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/email-messages/impl/src/main/java/org/pentaho/di/job/entries/getpop/MailConnection.java","lineNumber":930,"sourceCode":"\n  /**\n   * Save attached files to a folder.\n   *\n   * @param foldername\n   *          the target foldername\n   * @param pattern\n   *          regular expression to filter on files\n   * @throws KettleException\n   */\n  public void saveAttachedFiles( String foldername, Pattern pattern ) throws KettleException {\n    Object content = null;\n    try {\n      content = getMessage().getContent();\n      if ( content instanceof Multipart ) {\n        handleMultipart( foldername, (Multipart) content, pattern );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"MailConnection.Error.SavingAttachedFiles\", \"\"\n        + this.message.getMessageNumber(), foldername ), e );\n    } finally {\n      if ( content != null ) {\n        content = null;\n      }\n    }\n  }\n\n  private void handleMultipart( String foldername, Multipart multipart, Pattern pattern ) throws KettleException {\n    try {\n      for ( int i = 0, n = multipart.getCount(); i < n; i++ ) {\n        handlePart( foldername, multipart.getBodyPart( i ), pattern );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( e );\n    }\n  }\n","sourceCodeStart":912,"sourceCodeEnd":948,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/email-messages/impl/src/main/java/org/pentaho/di/job/entries/getpop/MailConnection.java#L912-L948","documentation":"The attachment-saving path (saveMessageAttachedFiles and its multipart handling) wraps exceptions from getMessage().getContent() and handleMultipart() into a KettleException with MailConnection.Error.SavingAttachedFiles, including message number and target folder. It means message content or its attachments could not be read/saved.","triggerScenarios":"During MailConnection use, content = getMessage().getContent() throws (MessagingException/IOException reading body parts) or handleMultipart fails writing an attachment file.","commonSituations":"Corrupted or non-MIME message bodies, nested multiparts with unsupported encodings, attachment filenames with illegal path characters, target folder missing or unwritable, disk full while saving large attachments.","solutions":["Check the chained cause — MessagingException during getContent means malformed MIME; skip or re-fetch that message.","Ensure the destination folder exists and is writable before saving attachments.","Sanitize attachment filenames from Content-Disposition headers (strip path separators and illegal chars).","Verify enough disk space for all attachments; process messages in batches."],"exampleFix":"// before\nString name = part.getFileName(); // may contain '/' or be null\nwriteToDisk(name, part.getInputStream());\n// after\nString name = BaseMessages sanitized: part.getFileName() == null ? \"unnamed\" : part.getFileName().replaceAll(\"[/\\\\\\\\:*?\\\"<>|]\", \"_\");\nwriteToDisk(name, part.getInputStream());","handlingStrategy":"try-catch","validationCode":"java.io.File dir = new java.io.File(targetFolder);\nif (!dir.isDirectory()) dir.mkdirs();\nif (!dir.canWrite()) throw new KettleException(\"No write permission: \" + targetFolder);\n// pre-check free space if attachments can be large","typeGuard":null,"tryCatchPattern":"try {\n  mailConnection.saveMessageAttachedFiles(pattern, targetFolder);\n} catch (KettleException e) {\n  logError(\"Attachment save failed for message \" + msgNr + \": \" + e.getCause().getMessage(), e);\n  // optionally skip this message and continue\n}","preventionTips":["Skip-and-log corrupted/non-MIME messages instead of failing the whole job","Sanitize attachment filenames from Content-Disposition headers","Pre-create and permission the attachment directory","Watch disk usage when saving large attachments in bulk"],"tags":["io","attachments","javamail","mime","kettle"],"backgroundTag":"file-write-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}