pentaho/pentaho-kettle · error · FileSystemException

FileSystemException wrapping SdkClientException

Error message

FileSystemException wrapping SdkClientException

What it means

getFileSystemOptions builds commons-vfs FileSystemOptions for the S3 chooser, reading AWS credentials (which may trigger SdkClientException, e.g. from the AWS credentials chain). Because the method declares FileSystemException, SdkClientException is wrapped and rethrown. The root cause is the nested SdkClientException.

Solutions

  1. Fix the AWS credential chain: set AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, repair ~/.aws/credentials, or enter keys in the dialog.
  2. Check the nested SdkClientException message to see which credential source failed.
  3. Verify the AWS profile name exists and the profile file has correct permissions.
  4. Confirm the AWS SDK dependency versions are consistent after plugin upgrades.

Example fix

// before
StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator( null, secretKey, accessKey );
// after: fail fast with a clear message when keys are absent
if ( accessKey == null || secretKey == null ) {
  throw new FileSystemException( "AWS access/secret key is required to browse S3" );
}
StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator( null, secretKey, accessKey );
Defensive patterns

Strategy: validation

Validate before calling

// ensure credentials exist before building options
boolean hasCreds = ( accessKey != null && secretKey != null )
  || System.getenv( "AWS_ACCESS_KEY_ID" ) != null
  || new java.io.File( System.getProperty( "user.home" ), ".aws/credentials" ).exists();
if ( !hasCreds ) throw new IllegalStateException( "No AWS credentials found in chain" );

Try / catch

try {
  FileSystemOptions opts = dialog.getFileSystemOptions();
} catch ( org.apache.commons.vfs2.FileSystemException e ) {
  Throwable cause = e.getCause();
  if ( cause instanceof software.amazon.awssdk.core.exception.SdkClientException ) {
    logError( "AWS credential resolution failed: " + cause.getMessage() );
  }
}

Prevention

When it happens

Trigger: resolveFile -> getFileSystemOptions where resolving AWS credentials (environment, profile, or the dialog's secret/access key fields) throws SdkClientException — e.g. no credentials found or profile file unreadable.

Common situations: No AWS credentials anywhere in the chain (env vars, ~/.aws/credentials, IAM role); malformed or unreadable AWS profile file; blank access/secret keys in the Spoon connection dialog; SDK version upgrade changing default credential chain behavior.

Related errors


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

Appendix: source

Thrown at plugins/s3-vfs/core/src/main/java/org/pentaho/amazon/s3/S3VfsFileChooserBaseDialog.java:125

      String accessKey = "";
      String secretKey = "";
      /* For legacy transformations containing AWS S3 access credentials, {@link Const#KETTLE_USE_AWS_DEFAULT_CREDENTIALS} can force Spoon to use
       * the Amazon Default Credentials Provider Chain instead of using the credentials embedded in the transformation metadata. */
      if ( !ValueMetaBase.convertStringToBoolean( Const.NVL( EnvUtil.getSystemProperty( Const.KETTLE_USE_AWS_DEFAULT_CREDENTIALS ), "N" ) ) ) {
        accessKey = System.getProperty( S3Util.ACCESS_KEY_SYSTEM_PROPERTY );
        secretKey = System.getProperty( S3Util.SECRET_KEY_SYSTEM_PROPERTY );
      } else {
        AWSCredentials credentials = S3CredentialsProvider.getAWSCredentials();
        if ( credentials != null ) {
          accessKey = credentials.getAWSAccessKeyId();
          secretKey = credentials.getAWSSecretKey();
        }
      }
      StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator( null, secretKey, accessKey );
      DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator( opts, userAuthenticator );

    } catch ( SdkClientException e ) {
      throw new FileSystemException( e );
    }
    return opts;
  }

  private VariableSpace getVariableSpace() {
    if ( Spoon.getInstance().getActiveTransformation() != null ) {
      return Spoon.getInstance().getActiveTransformation();
    } else if ( Spoon.getInstance().getActiveJob() != null ) {
      return Spoon.getInstance().getActiveJob();
    } else {
      return new Variables();
    }
  }
}

View on GitHub (pinned to f3058517a1)