{"record":{"id":"25849014d9a95356","repo":"pentaho/pentaho-kettle","slug":"cannot-open-control-file-path-controlfile","errorCode":null,"errorMessage":"Cannot open control file [path=${controlFile}]","messagePattern":"Cannot open control file \\[path=(.+?)\\]","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/terafast-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/terafastbulkloader/TeraFast.java","lineNumber":367,"sourceCode":"    }\n  }\n\n  /**\n   * Invoke loading with control file.\n   *\n   * @throws KettleException\n   *           ...\n   */\n  private void invokeLoadingControlFile() throws KettleException {\n    File controlFile = null;\n    final InputStream control;\n    final String controlContent;\n    try {\n      controlFile = new File( resolveFileName( this.meta.getControlFile().getValue() ) );\n      control = FileUtils.openInputStream( controlFile );\n      controlContent = environmentSubstitute( FileUtils.readFileToString( controlFile ) );\n    } catch ( IOException e ) {\n      throw new KettleException( \"Cannot open control file [path=\" + controlFile + \"]\", e );\n    }\n    try {\n      IOUtils.write( controlContent, this.fastload );\n      this.fastload.flush();\n    } catch ( IOException e ) {\n      throw new KettleException( \"Cannot pipe content of control file to fastload [path=\" + controlFile + \"]\", e );\n    } finally {\n      IOUtils.closeQuietly( control );\n      IOUtils.closeQuietly( this.fastload );\n    }\n  }\n\n  /**\n   * Invoke loading with loading commands.\n   *\n   * @throws KettleException\n   *           ...\n   */","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/terafast-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/terafastbulkloader/TeraFast.java#L349-L385","documentation":"invokeLoadingControlFile opens the fastload control file with FileUtils.openInputStream; an IOException there (file missing, unreadable, path is a directory) is wrapped as 'Cannot open control file [path=...]'. The control file holds the FastLoad script and must be readable before its content is piped to the running fastload process.","triggerScenarios":"execute() -> invokeLoadingControlFile(): meta.getControlFile().getValue() resolves (after resolveFileName) to a non-existent file, a directory, or a file the current OS user cannot read, so FileUtils.openInputStream/readFileToString throws IOException.","commonSituations":"Control file was never generated (e.g. 'generate control file' option disabled but a path still configured); typo or wrong variable value in the control file path; file generated on another host/agent; permission tightened after generation; path uses Windows separators on Linux.","solutions":["Verify the control file path resolves and exists: ls -l <resolved-path>; regenerate the control file if it was deleted.","Fix variable substitution: log or print resolveFileName(meta.getControlFile().getValue()) and confirm the ${VARIABLE} values at runtime.","Grant read permission on the control file and its parent directory to the Kettle run user.","Confirm the path points to a file, not a directory, and uses OS-appropriate separators.","If the control file is expected to be auto-generated by TeraFast, enable the generation option or run the prerequisite step first."],"exampleFix":"// before\ncontrol = FileUtils.openInputStream( controlFile );\n// after\nif ( !controlFile.isFile() || !controlFile.canRead() ) {\n  throw new KettleException( \"Control file missing or unreadable: \" + controlFile.getAbsolutePath() ); // fail with actionable message\n}\ncontrol = FileUtils.openInputStream( controlFile );","handlingStrategy":"validation","validationCode":"import java.io.File;\nString resolved = resolveFileName( controlFileValue );\nFile cf = new File( resolved );\nif ( !cf.exists() ) throw new IllegalStateException( \"Control file does not exist: \" + cf.getAbsolutePath() );\nif ( !cf.isFile() ) throw new IllegalStateException( \"Control file path is not a file: \" + cf.getAbsolutePath() );\nif ( !cf.canRead() ) throw new IllegalStateException( \"Control file not readable by current user: \" + cf.getAbsolutePath() );","typeGuard":"boolean isReadableFile( String path ) {\n  File f = new File( path );\n  return f.isFile() && f.canRead();\n}","tryCatchPattern":"try {\n  control = FileUtils.openInputStream( controlFile );\n  controlContent = environmentSubstitute( FileUtils.readFileToString( controlFile ) );\n} catch ( IOException e ) {\n  throw new KettleException( \"Cannot open control file [path=\" + controlFile.getAbsolutePath()\n    + \"]; verify the file exists, is readable, and variables resolve correctly\", e );\n}","preventionTips":["Generate the control file in a prior step (or enable auto-generation) before invoking the load.","Use absolute paths and verify ${variable} resolution with a variable preview.","Ensure read permissions for the Kettle run user on the file and its directory.","Avoid OS-specific separators; build paths with File/Paths APIs."],"tags":["kettle","pdi","teradata","fastload","io","file"],"backgroundTag":"file-open-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"}