pentaho/pentaho-kettle · error · KettleException

Error while executing psql \'

Error message

Error while executing psql \'

What it means

execute() runs the fully assembled psql command via Runtime exec / process handling. If that execution throws any exception other than a KettleException (e.g. IOException because the executable cannot be spawned, or a process-interrupt failure), it is wrapped in a KettleException whose message embeds the command line built with password=false. The wrapped cause contains the real OS-level error.

Solutions

  1. Copy the command line from the exception message and run it manually in a shell to see the OS error.
  2. Verify the psql path exists and is executable for the Kettle process user (chmod +x, correct path, correct OS).
  3. Check that the transformation runs on the machine where psql is installed, or install psql client locally.
  4. Inspect ex.getCause() (usually IOException: Cannot run program ...) for the exact OS-level reason.

Example fix

// before (wrong platform path in step)
psql path = /usr/local/greenplum-db/bin/psql   (running on Windows)

// after
psql path = C:\Program Files\PostgreSQL\14\bin\psql.exe
Defensive patterns

Strategy: try-catch

Validate before calling

String psql = transformation.environmentSubstitute(meta.getPsqlpath());
java.io.File f = new java.io.File(psql);
if (!f.isFile() || !f.canExecute())
  throw new IllegalArgumentException("psql missing or not executable: " + psql);

Try / catch

try {
  execute(meta, wait);
} catch (KettleException e) {
  if (e.getMessage().startsWith("Error while executing psql")) {
    logError("psql spawn failed", e.getCause());
    String cmd = e.getMessage(); // embedded command line, safe to run manually for diagnosis
    logError("Reproduce manually: " + cmd);
  } else throw e;
}

Prevention

When it happens

Trigger: execute(meta, wait) catches a non-KettleException from running the psql process: the executable path is wrong/non-executable so ProcessBuilder/Runtime.exec throws IOException; insufficient permissions; the OS cannot fork; or the command file resolution succeeded earlier but spawning fails at runtime.

Common situations: psql path points to a file that does not exist on the machine running the transformation (especially when Spoon runs locally but psql lives on a server); the psql binary lacks the execute bit; disk/memory exhaustion prevents process creation; Windows environment where a UNIX-style path was configured.

Related errors


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

Appendix: source

Thrown at plugins/gp-bulk-loader/core/src/main/java/org/pentaho/di/trans/steps/gpbulkloader/GPBulkLoader.java:424

      // any output?
      StreamLogger outputLogger = new StreamLogger( psqlProcess.getInputStream(), "OUTPUT" );

      // kick them off
      errorLogger.start();
      outputLogger.start();

      if ( wait ) {
        // any error???
        int exitVal = psqlProcess.waitFor();
        logBasic( BaseMessages.getString( PKG, "GPBulkLoader.Log.ExitValuePsqlPath", "" + exitVal ) );
      }
    } catch ( KettleException ke ) {
      // Re-throw the exception to the caller.
      throw ke;
    } catch ( Exception ex ) {
      // The message below doesn't include the password since passwords aren't supported.
      throw new KettleException( "Error while executing psql \'" + createCommandLine( meta, false ) + "\'", ex );
    }

    return true;
  }

  public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
    meta = (GPBulkLoaderMeta) smi;
    data = (GPBulkLoaderData) sdi;

    try {
      Object[] r = getRow(); // Get row from input rowset & set row busy!
      if ( r == null ) {
        // no more input to be expected...

        setOutputDone();

        if ( !preview ) {
          if ( output != null ) {

View on GitHub (pinned to f3058517a1)