pentaho/pentaho-kettle · error · KettleException

No control file specified

Error message

No control file specified

What it means

sqlldr cannot run without a control file, so createCommandLine demands one: if meta.getControlFile() is null or empty after the sqlldr executable, this KettleException is thrown instead of appending control='...' to the command line.

Solutions

  1. Set the control file field in the step dialog to a path the step can write to, e.g. /tmp/orabulk/load.ctl.
  2. Ensure the target directory exists and the runtime user has write permission.
  3. Re-save and validate the transformation so the field persists in the ktr.

Example fix

// before
<control_file/>
// after
<control_file>/tmp/orabulk/load.ctl</control_file>
Defensive patterns

Strategy: validation

Validate before calling

// Java: verify a control file location is configured before execution
if (meta.getControlFile() == null || meta.getControlFile().trim().isEmpty()) {
  throw new IllegalArgumentException(
    "Oracle Bulk Loader: control file path is required, e.g. /tmp/orabulk/load.ctl");
}

Try / catch

try {
  trans.execute(null);
} catch (KettleException e) {
  if (String.valueOf(e.getMessage()).contains("No control file specified")) {
    // guide user to set the control file field in the step dialog
  }
}

Prevention

When it happens

Trigger: meta.getControlFile() == null when createCommandLine is invoked from execute — the control file name/directory field is blank in the step settings.

Common situations: User assumed the step auto-generates and auto-names the control file location but left the field empty; configuration exported/imported and the field lost; running headless with a ktr whose step config is incomplete.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at plugins/oracle-bulk-loader/impl/src/main/java/org/pentaho/di/trans/steps/orabulkloader/OraBulkLoader.java:373

        throw new KettleException( "Error retrieving sqlldr string", ex );
      }
    } else {
      throw new KettleException( "No sqlldr application specified" );
    }

    if ( meta.getControlFile() != null ) {
      try {
        FileObject fileObject =
          getFileObject( meta.getControlFile(), getTransMeta() );

        sb.append( " control=\'" );
        sb.append( getFilename( fileObject ) );
        sb.append( "\'" );
      } catch ( KettleFileException ex ) {
        throw new KettleException( "Error retrieving controlfile string", ex );
      }
    } else {
      throw new KettleException( "No control file specified" );
    }

    if ( OraBulkLoaderMeta.METHOD_AUTO_CONCURRENT.equals( meta.getLoadMethod() ) ) {
      sb.append( " data=\'-\'" );
    }

    if ( meta.getLogFile() != null ) {
      try {
        FileObject fileObject =
          getFileObject( meta.getLogFile(), getTransMeta() );

        sb.append( " log=\'" );
        sb.append( getFilename( fileObject ) );
        sb.append( "\'" );
      } catch ( KettleFileException ex ) {
        throw new KettleException( "Error retrieving logfile string", ex );
      }
    }

View on GitHub (pinned to f3058517a1)