pentaho/pentaho-kettle · error · KettleException

Error retrieving logfile string

Error message

Error retrieving logfile string

What it means

When meta.getLogFile() is set, createCommandLine() resolves the log file path via environmentSubstitute() and KettleVFS to append '-o <logfile>' to the psql command. Any exception in that resolution is wrapped in this KettleException with the original error as cause. This is a path-resolution wrapper error, not a validation error (a missing log file is optional).

Solutions

  1. Inspect ex.getCause() for the underlying VFS failure and fix it (missing provider, bad scheme, permissions).
  2. Make sure every variable in the log path is defined (kettle.properties, transformation parameters, or runtime env).
  3. Use a plain absolute local path (e.g. /var/log/kettle/gpbulk.log) if VFS complexity is not needed.
  4. If logging is unnecessary, clear the log file field entirely - the step skips this block when it is null.

Example fix

// before
Log file: ${LOG_DIR}/gpbulk.log   (LOG_DIR undefined)

// after
kettle.properties: LOG_DIR=/var/log/kettle
Log file: ${LOG_DIR}/gpbulk.log
Defensive patterns

Strategy: validation

Validate before calling

String log = meta.getLogFile();
if (log != null && !log.trim().isEmpty()) {
  String resolved = transformation.environmentSubstitute(log);
  if (resolved.contains("${"))
    throw new IllegalArgumentException("Unresolved variable in log path: " + log);
  java.io.File dir = new java.io.File(resolved).getParentFile();
  if (dir != null && !dir.canWrite())
    throw new IllegalArgumentException("Log dir not writable: " + dir);
}

Try / catch

try {
  execute(meta, wait);
} catch (KettleException e) {
  if (e.getMessage().contains("Error retrieving logfile string")) {
    logError("Log file path resolution failed, continuing without log", e.getCause());
    meta.setLogFile(null); // log file is optional; retry without it
    execute(meta, wait);
  } else throw e;
}

Prevention

When it happens

Trigger: createCommandLine() runs with meta.getLogFile() non-null and KettleVFS.getFileObject(environmentSubstitute(logFile)) throws: unsupported VFS scheme, invalid path, IO failure, or unresolvable ${VAR} inside the log file path.

Common situations: Log path uses a variable undefined at runtime; log directory on a network share not mounted or not covered by a VFS provider; filename contains characters VFS rejects; path points to a scheme like s3:// unsupported by the installed VFS plugins.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

        sb.append( " -n -f " );
        sb.append( enclosure ).append( KettleVFS.getFilename( fileObject ) ).append( enclosure );
      } catch ( Exception ex ) {
        throw new KettleException( "Error retrieving controlfile string", ex );
      }
    } else {
      throw new KettleException( "No control file specified" );
    }

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

        sb.append( " -o " );
        sb.append( enclosure ).append( KettleVFS.getFilename( fileObject ) ).append( enclosure );
      } catch ( Exception ex ) {
        throw new KettleException( "Error retrieving logfile string", ex );
      }
    }

    DatabaseMeta dm = meta.getDatabaseMeta();
    if ( dm != null ) {
      String user = Const.NVL( dm.getUsername(), "" );

      // Passwords will not work for now because we can't get them to the command line without assuming UNIX and using
      // an environment variable
      String pass = Const.NVL( dm.getPassword(), "" );
      if ( password && !pass.equalsIgnoreCase( "" ) ) {
        throw new KettleException(
          "Passwords are not supported directly, try configuring "
            + "your connection for trusted access using pg_hba.conf" );
      }
      // if ( ! password )
      // {
      // pass = "******";

View on GitHub (pinned to f3058517a1)