pentaho/pentaho-kettle · error · KettleStepException

SFTPPut.Error.RemoteFilenameFieldMissing

Error message

SFTPPut.Error.RemoteFilenameFieldMissing

What it means

Thrown when the SFTPPut step is configured to read source data from an input stream (meta.isInputStream() is true) but no remote filename field is configured or resolvable (data.indexOfRemoteFilename == -1). In stream mode the destination filename cannot be derived from a file name, so an explicit remote filename field is mandatory. The step fails fast with KettleStepException before attempting the upload.

Solutions

  1. Open the SFTPPut step dialog and set the remote filename field while in input-stream mode.
  2. Verify the configured remote filename field actually exists in the incoming stream (use 'Get Fields').
  3. If a file-based upload is intended, disable the input stream option so the destination name defaults to the file's base name.
  4. Fix upstream steps so the remote filename field is present and named identically.

Example fix

// before (dialog/config): stream mode with no remote filename field
source = inputStream; remoteFilenameField = null;
// after
source = inputStream; remoteFilenameField = "remote_target_name";
Defensive patterns

Strategy: validation

Validate before calling

// before running, verify stream mode has a remote filename field present
String[] fields = rowMeta.getFieldNames();
if (isStreamMode && (remoteFilenameField == null || !Arrays.asList(fields).contains(remoteFilenameField))) {
  throw new IllegalStateException("input-stream mode requires an existing remote filename field");
}

Try / catch

try {
  transform.execute();
} catch (KettleStepException e) {
  if (e.getMessage().contains("RemoteFilenameFieldMissing")) {
    log.error("Set the remote filename field in SFTPPut dialog when using input stream mode");
  } else { throw e; }
}

Prevention

When it happens

Trigger: Input stream mode is enabled and the 'remote filename' field is not specified in the dialog, or the specified field is absent from the row layout so its index resolves to -1.

Common situations: Switching the step from file mode to stream mode without also setting the remote filename field; renaming the remote filename field upstream; getting fields from the wrong previous step so the field never appears in the row meta.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at plugins/sftpput/impl/src/main/java/org/pentaho/di/trans/steps/sftpput/SFTPPut.java:169

    InputStream inputStream = null;
    FileObject destinationFolder = null;
    String destinationFilename;
    FileObject file = null;

    try {
      if ( Utils.isEmpty( sourceData ) ) {
        // Source data is empty
        throw new KettleStepException( BaseMessages.getString( PKG, "SFTPPut.Error.SourceDataEmpty" ) );
      }

      if ( meta.isInputStream() ) {
        // Source data is a stream
        inputStream = new ByteArrayInputStream( getInputRowMeta().getBinary( r, data.indexOfSourceFileFieldName ) );

        if ( data.indexOfRemoteFilename == -1 ) {
          // for the case when put data is transferred via input field
          // it is mandatory to specify remote file name
          throw new KettleStepException( BaseMessages.getString( PKG, "SFTPPut.Error.RemoteFilenameFieldMissing" ) );
        }
        destinationFilename = getInputRowMeta().getString( r, data.indexOfRemoteFilename );
      } else {
        // source data is a file
        // let's check file
        file = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( sourceData );

        if ( !file.exists() ) {
          // We can not find file
          throw new KettleStepException( BaseMessages.getString( PKG, "SFTPPut.Error.CanNotFindField", sourceData ) );
        }
        // get stream from file
        inputStream = KettleVFS.getInputStream( file );

        // Destination filename
        destinationFilename = file.getName().getBaseName();
      }

View on GitHub (pinned to f3058517a1)