pentaho/pentaho-kettle · error · KettleException

Internal error: no sqlldr process running

Error message

Internal error: no sqlldr process running

What it means

At the end of the stream-load path processRow expects a running sqlldr process to wait for; if sqlldrProcess is null on a non-first row it throws this internal invariant error. It indicates the process handle was consumed or never created despite rows being processed.

Solutions

  1. Re-run the transformation; this is an internal state error, often secondary to an earlier swallowed failure
  2. Check earlier step logs for a failed execute() that never spawned sqlldr
  3. Report/inspect with the Pentaho version — if reproducible with a clean transformation it is a step bug
  4. Switch the load method to 'auto conventional' as a workaround if the streaming path keeps corrupting state
Defensive patterns

Strategy: retry

Try / catch

try {
  step.processRow( smi, sdi );
} catch ( KettleException e ) {
  if ( e.getMessage().contains( "no sqlldr process running" ) ) {
    // internal state issue: restart the transformation from a clean state
  }
}

Prevention

When it happens

Trigger: load method is 'wait for database stream', first==false, and sqlldrProcess == null when the step reaches the waitFor block — i.e. the process handle was already nulled or execute() failed to spawn it.

Common situations: Race or re-entry into processRow after the process already completed; a failed/aborted prior batch leaving data.sqlldrProcess null; programming-level state corruption rather than a user configuration problem.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

          }

          String loadMethod = meta.getLoadMethod();
          if ( OraBulkLoaderMeta.METHOD_AUTO_END.equals( loadMethod ) ) {
            // if this is the first line, we do not need to execute loader
            // control file may not exists
            if ( !first ) {
              execute( meta, true );
              sqlldrProcess = null;
            }
          } else if ( OraBulkLoaderMeta.METHOD_AUTO_CONCURRENT.equals( meta.getLoadMethod() ) ) {
            try {
              if ( sqlldrProcess != null ) {
                int exitVal = sqlldrProcess.waitFor();
                sqlldrProcess = null;
                logBasic( BaseMessages.getString( PKG, "OraBulkLoader.Log.ExitValueSqlldr", "" + exitVal ) );
                checkExitVal( exitVal );
              } else if ( !first ) {
                throw new KettleException( "Internal error: no sqlldr process running" );
              }
            } catch ( Exception ex ) {
              throw new KettleException( "Error while executing sqlldr", ex );
            }
          }
        }
        return false;
      }

      if ( !preview ) {
        if ( first ) {
          first = false;

          String recTerm = Const.CR;
          if ( !Utils.isEmpty( meta.getAltRecordTerm() ) ) {
            recTerm = substituteRecordTerminator( meta.getAltRecordTerm() );
          }

View on GitHub (pinned to f3058517a1)