pentaho/pentaho-kettle · error · KettleException

HTTP.Log.UnableGetResult

HTTP.Log.UnableGetResult

Error message

HTTP.Log.UnableGetResult

What it means

KettleStep/HTTP step wraps any unexpected failure while executing the HTTP request in callHttpService into a KettleException with message 'HTTP.Log.UnableGetResult'. It is the generic catch-all after the request was built and sent; the original cause (connect failure, protocol error, response parsing failure) is attached as the cause. UnknownHostException is handled separately before this branch.

Solutions

  1. Inspect the chained cause exception in the Kettle log to get the real root cause (connect/SSL/timeout).
  2. Verify the URL is reachable: curl the exact substituted URL from the same host running Pentaho.
  3. Check network path: proxy settings (in kettle.properties or -Dhttp.proxyHost), firewall, DNS resolution.
  4. If SSL-related, import the server certificate into the JVM truststore or configure an SSL trust manager.
  5. Encode/validate the URL in constructUrlBuilder (URIBuilder) so substituted values produce a valid URI.

Example fix

// before
String url = "${BASE_URL}/api"; // substituted value contains a space
// after
String url = environmentSubstitute( "${BASE_URL}" ) + "/api";
// or in code: URIBuilder encodes params via addParameter, not manual string concat
Defensive patterns

Strategy: try-catch

Validate before calling

// validate the substituted URL is well-formed and resolvable before running the transformation
URI u = new URI( environmentSubstitute( urlSetting ) );
if ( u.getScheme() == null || (!u.getScheme().equals("http") && !u.getScheme().equals("https")) ) throw new IllegalArgumentException( "invalid URL: " + u );

Try / catch

try { newRow = callHttpService( ... ); } catch ( KettleException e ) {
  Throwable root = e; while ( root.getCause() != null ) root = root.getCause();
  logError( "HTTP call failed: " + root.getMessage(), e );
  // route row to error stream or retry with backoff
}

Prevention

When it happens

Trigger: callHttpService throws any Exception other than UnknownHostException while opening/executing the HttpClient call against the row's URL (connection refused, connect timeout, SSL handshake failure, URI with illegal characters reaching execute, response stream read failure).

Common situations: Target host unreachable or port closed; HTTPS endpoint with untrusted/self-signed certificate; URL containing spaces or unencoded characters after variable substitution; proxy/firewall blocking the request; remote server resetting the connection mid-response.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/http/HTTP.java:240

          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, new Long( responseTime ) );
          returnFieldsOffset++;
        }
        if ( !Utils.isEmpty( meta.getResponseHeaderFieldName() ) ) {
          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, headerString );
        }

      } finally {
        if ( httpResponse != null ) {
          httpResponse.close();
        }
        // Release current connection to the connection pool once you are done
        method.releaseConnection();
      }
      return newRow;
    } catch ( UnknownHostException uhe ) {
      throw new KettleException( BaseMessages.getString( PKG, "HTTP.Error.UnknownHostException", uhe.getMessage() ) );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "HTTP.Log.UnableGetResult", uri ), e );
    }
  }

  private URIBuilder constructUrlBuilder( RowMetaInterface outputRowMeta, Object[] row ) throws KettleValueException,
    KettleException {
    URIBuilder uriBuilder;
    try {
      String baseUrl = data.realUrl;
      if ( meta.isUrlInField() ) {
        // get dynamic url
        baseUrl = outputRowMeta.getString( row, data.indexOfUrlField );
      }

      if ( isDetailed() ) {
        logDetailed( BaseMessages.getString( PKG, "HTTP.Log.Connecting", baseUrl ) );
      }

      uriBuilder = new URIBuilder( baseUrl ); // the base URL with variable substitution

View on GitHub (pinned to f3058517a1)