pentaho/pentaho-kettle · error · KettleException

Rest.Error.IOException

Rest.Error.IOException

Error message

Rest.Error.IOException

What it means

Wraps a java.io.IOException thrown during SSL setup in setSSLConfiguration (called by setConfig) while loading the trust/keystore. The message is the generic localized 'Error'. IOException here usually means the trust store file exists but is corrupt, has the wrong password, or is in an unexpected format.

Solutions

  1. Validate the trust store with 'keytool -list -v -keystore <file>' using the configured password; re-export the store if keytool fails.
  2. Re-check the trust store password setting in the step — a wrong password typically surfaces as an IOException from KeyStore.load.
  3. Recreate the trust store: keytool -importcert -file ca.crt -keystore truststore.jks.
  4. Confirm the file transferred in binary mode and is not truncated (compare file sizes/checksums).

Example fix

// before
certutil -encode ca.crt ca.pem   # wrong format fed to java keystore
// after — build a proper JKS trust store
keytool -importcert -alias ca -file ca.pem -keystore truststore.jks -storepass changeit -noprompt
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the store before configuring the step
try (InputStream in = new FileInputStream(trustStoreFile)) {
  KeyStore ks = KeyStore.getInstance("JKS");
  ks.load(in, storePassword.toCharArray()); // throws IOException if corrupt/wrong password
}

Try / catch

try { setSSLConfiguration(); } catch (KettleException e) {
  if (e.getCause() instanceof IOException) { /* validate keystore file + password */ }
  throw e;
}

Prevention

When it happens

Trigger: KeyStore.load(InputStream, password) or the SSLContext/TrustManagerFactory initialization fails with an I/O problem: truncated/corrupt .jks/.p12 file, wrong store password, or file that is a directory/locked.

Common situations: Trust store created with a newer Java format than the runtime JCE supports; file corrupted in transfer (FTP ASCII mode); password containing characters mangled by variable substitution; store exported from Windows certmgr in a format Java cannot parse.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at plugins/rest/core/src/main/java/org/pentaho/di/trans/steps/rest/Rest.java:373

    }
  }

  protected void setSSLConfiguration( RestData data ) throws KettleException {
    try ( var trustStoreIn = getInputStream( data.trustStoreFile ) ) {
      data.sslContext = HttpClientManager.getSslContext( meta.isIgnoreSsl(),
        trustStoreIn,
        data.trustStorePassword );

    } catch ( NoSuchAlgorithmException e ) {
      throw new KettleException( BaseMessages.getString( PKG, "Rest.Error.NoSuchAlgorithm" ), e );
    } catch ( KeyStoreException e ) {
      throw new KettleException( BaseMessages.getString( PKG, "Rest.Error.KeyStoreException" ), e );
    } catch ( CertificateException e ) {
      throw new KettleException( BaseMessages.getString( PKG, "Rest.Error.CertificateException" ), e );
    } catch ( FileNotFoundException e ) {
      throw new KettleException( BaseMessages.getString( PKG, "Rest.Error.FileNotFound", data.trustStoreFile ), e );
    } catch ( IOException e ) {
      throw new KettleException( BaseMessages.getString( PKG, "Rest.Error.IOException" ), e );
    } catch ( KeyManagementException | UnrecoverableKeyException e ) {
      throw new KettleException( BaseMessages.getString( PKG, "Rest.Error.KeyManagementException" ), e );
    }
  }

  /**
   * Get an InputStream for the file with the given name.
   * If the file name is empty or null, returns null.
   *
   * @param fileName the file name to get InputStream from
   * @return InputStream for the given file, <code>null</code> if the given file name is empty or null
   * @throws KettleException if any error occurs while getting the InputStream
   */
  protected InputStream getInputStream( String fileName ) throws KettleException {
    InputStream inputStream = null;

    if ( !StringUtil.isEmpty( fileName ) ) {
      fileName = fileName.trim();

View on GitHub (pinned to f3058517a1)