{"record":{"id":"150754a5444d0b93","repo":"pentaho/pentaho-kettle","slug":"kettlevfs-exception-parentdirectorydoesnotexist","errorCode":"KettleVFS.Exception.ParentDirectoryDoesNotExist","errorMessage":"KettleVFS.Exception.ParentDirectoryDoesNotExist","messagePattern":"KettleVFS\\.Exception\\.ParentDirectoryDoesNotExist","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/vfs/KettleVFSImpl.java","lineNumber":326,"sourceCode":"  }\n\n  @Override\n  public InputStream getInputStream( String vfsFilename, VariableSpace space ) throws KettleFileException {\n    try {\n      FileObject fileObject = getFileObject( vfsFilename, space );\n\n      return KettleVFS.getInputStream( fileObject );\n    } catch ( IOException e ) {\n      throw new KettleFileException( e );\n    }\n  }\n\n  @Override\n  public OutputStream getOutputStream( FileObject fileObject, boolean append ) throws IOException {\n    FileObject parent = fileObject.getParent();\n    if ( parent != null ) {\n      if ( !parent.exists() ) {\n        throw new IOException( BaseMessages.getString(\n          PKG, \"KettleVFS.Exception.ParentDirectoryDoesNotExist\", KettleVFS.getFriendlyURI( parent ) ) );\n      }\n    }\n    try {\n      fileObject.createFile();\n      FileContent content = fileObject.getContent();\n      return content.getOutputStream( append );\n    } catch ( FileSystemException e ) {\n      // Perhaps if it's a local file, we can retry using the standard\n      // File object. This is because on Windows there is a bug in VFS.\n      //\n      if ( fileObject instanceof LocalFile ) {\n        try {\n          String filename = KettleVFS.getFilename( fileObject );\n          return new FileOutputStream( new File( filename ), append );\n        } catch ( Exception e2 ) {\n          throw e; // throw the original exception: hide the retry.\n        }","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/vfs/KettleVFSImpl.java#L308-L344","documentation":"KettleVFSImpl.getOutputStream(FileObject, append) refuses to open an output stream when the file's parent directory does not exist, throwing an IOException with localized message KettleVFS.Exception.ParentDirectoryDoesNotExist (including the friendly parent URI). This is a pre-check to avoid creating orphan files or confusing failures in createFile().","triggerScenarios":"Calling KettleVFS.getOutputStream / fileObject content write where the target directory hasn't been created yet — e.g. writing to /data/out/report.csv when /data/out is missing, or sftp paths whose remote directory doesn't exist.","commonSituations":"Job writes to a dated output folder (e.g. /out/2026/09/13) nobody created; remote SFTP upload directory missing; typo in the directory part of the path; environment change where a mounted directory isn't present.","solutions":["Create the parent directory first: KettleVFS.createDirectory(parent) or parent.createFolder() on the FileObject.","In jobs/transformations, add a 'Create a folder' step or pre-create the directory in the script that runs the job.","Fix typos in the directory portion of the output path.","For SFTP, verify the remote directory exists and the user has permission to create/write there."],"exampleFix":"// before\nOutputStream os = KettleVFS.getOutputStream(KettleVFS.getFileObject(\"file:///data/out/report.csv\"), false);\n// after\nFileObject fo = KettleVFS.getFileObject(\"file:///data/out/report.csv\");\nFileObject parent = fo.getParent();\nif (parent != null && !parent.exists()) parent.createFolder();\nOutputStream os = KettleVFS.getOutputStream(fo, false);","handlingStrategy":"validation","validationCode":"FileObject parent = fo.getParent();\nif (parent != null && !parent.exists()) parent.createFolder(); // ensure directory before writing","typeGuard":null,"tryCatchPattern":"try (OutputStream os = KettleVFS.getOutputStream(fo, false)) {\n  // write\n} catch (IOException e) {\n  if (e.getMessage().contains(\"ParentDirectoryDoesNotExist\")) {\n    fo.getParent().createFolder();\n    // retry write once\n  } else throw e;\n}","preventionTips":["Create dated/output directories as an explicit job step before writing files.","For SFTP, pre-create remote directories and verify write permissions.","Extract directory creation into a shared helper used by all output steps."],"tags":["vfs","io","directory-not-found","file-write"],"backgroundTag":"directory-not-found","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"}