pentaho/pentaho-kettle · error · KettleException

SecretKeyGenerator.KeyGenerationError

SecretKeyGenerator.KeyGenerationError

Error message

SecretKeyGenerator.KeyGenerationError

What it means

KettleException thrown by SecretKeyGenerator.processRow when the underlying CryptoException occurs while generating a symmetric secret key (e.g., AES/DES) for the crypto transform at index i — either raw bytes via generateKey or hex via generateKeyAsHex for the configured key length. The message includes the failing algorithm index and the CryptoException is chained as the cause.

Solutions

  1. Read the chained CryptoException (getCause()) to see the exact JCE failure (InvalidKeyException/NoSuchAlgorithmException).
  2. Set the key length to one supported by the algorithm (e.g., 128/192/256 for AES; 64/112/168 for DESede) in the step dialog.
  3. Install the JCE Unlimited Strength policy files or run a modern JDK (8u161+) that enables unlimited crypto by default.
  4. Verify the required security provider/algorithm is available in the JVM (check java.security configuration / FIPS restrictions).

Example fix

// before: 256-bit key on restricted JVM
meta.setSecretKeyLen(new int[]{256});
// after: supported length
meta.setSecretKeyLen(new int[]{128});
Defensive patterns

Strategy: validation

Validate before calling

// verify the key length is valid for the algorithm before running
int len = meta.getSecretKeyLen()[i];
Set<Integer> allowed = Set.of( 128, 192, 256 ); // AES
if ( !allowed.contains( len ) ) throw new IllegalArgumentException( "Unsupported key length for AES: " + len );
// also confirm max key length
if ( Cipher.getMaxAllowedKeyLength( "AES" ) < len ) throw new IllegalStateException( "JCE limited to " + Cipher.getMaxAllowedKeyLength( "AES" ) );

Try / catch

try { trans.execute( null ); } catch ( KettleException e ) { Throwable c = e.getCause(); if ( c instanceof CryptoException ) log.error( "Key generation failed: " + c.getMessage(), c ); throw e; }

Prevention

When it happens

Trigger: Requesting a key length unsupported by the algorithm/JCE policy (e.g., 256-bit AES with unlimited-strength policies absent in old JDKs), an unavailable crypto algorithm/provider, or an invalid key-length value that SecretKeyGenerator.init fails to enforce.

Common situations: Running an old JDK without JCE Unlimited Strength policy files requesting 256-bit keys; picking a key size not divisible by 8 or out of the algorithm's range; restricted crypto providers on hardened JVMs (FIPS mode); typo'd algorithm names in the step configuration.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/symmetriccrypto/secretkeygenerator/SecretKeyGenerator.java:114

      for ( int j = 0; j < data.secretKeyCount[i] && !isStopped(); j++ ) {

        // Create a new row
        row = buildEmptyRow();
        incrementLinesRead();

        int index = 0;

        try {
          // Return secret key
          if ( meta.isOutputKeyInBinary() ) {
            row[index++] = data.cryptoTrans[i].generateKey( data.secretKeyLen[i] );
          } else {
            row[index++] = data.cryptoTrans[i].generateKeyAsHex( data.secretKeyLen[i] );
          }

        } catch ( CryptoException k ) {
          throw new KettleException( BaseMessages.getString( PKG, "SecretKeyGenerator.KeyGenerationError", i ), k );
        }

        if ( data.addAlgorithmOutput ) {
          // add algorithm
          row[index++] = meta.getAlgorithm()[i];
        }

        if ( data.addSecretKeyLengthOutput ) {
          // add secret key len
          row[index++] = new Long( data.secretKeyLen[i] );
        }

        if ( data.readsRows ) {
          // build output row
          row = RowDataUtil.addRowData( rowIn, data.prevNrField, row );
        }

        if ( isRowLevel() ) {

View on GitHub (pinned to f3058517a1)