pentaho/pentaho-kettle · error · KettleException

HTTPPOST.Error.CanNotReadURL

Error message

HTTPPOST.Error.CanNotReadURL

What it means

Generic catch-all in callHTTPPOST: any exception during the HTTP POST (connection refused, timeout, SSL errors, malformed URL, IO errors) is wrapped in a KettleException with 'HTTPPOST.Error.CanNotReadURL' and data.realUrl interpolated. It means the step could not successfully read from the configured URL.

Solutions

  1. Check data.realUrl (shown in the message) is reachable: curl -v the same URL from the PDI machine.
  2. Verify the server is running, port open, and firewall/proxy rules allow the request.
  3. Fix SSL issues (import server cert into the JVM truststore) if the error is a certificate problem.
  4. Inspect the wrapped cause (e.getCause()) in the stack trace for the precise failure; adjust timeouts/connection settings accordingly.

Example fix

// before
String url = "http://api.example.com:8085/endpoint"; // wrong port
// after
String url = "http://api.example.com:8080/endpoint"; // correct, reachable endpoint
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the endpoint is reachable before the POST
HttpURLConnection c = (HttpURLConnection) new URL(realUrl).openConnection();
c.setConnectTimeout(5000); c.setRequestMethod("HEAD");
if (c.getResponseCode() >= 400) throw new IllegalStateException("Endpoint unhealthy");

Type guard

boolean isUsableUrl(String u) {
  try { new java.net.URL(u); return true; } catch (Exception e) { return false; }
}

Try / catch

try {
  result = callHttpPost(url, params);
} catch (KettleException ke) {
  Throwable cause = ke.getCause();
  log.error("POST to " + realUrl + " failed: " + (cause != null ? cause : ke));
  // classify cause: refused/timeout/SSL and retry or fail over
}

Prevention

When it happens

Trigger: callHTTPPOST throws any Exception other than UnknownHostException while executing the HttpClient request or reading the response for data.realUrl; caught at line 324 and rethrown as KettleException with the CanNotReadURL message.

Common situations: Server down or port wrong (connection refused); TLS certificate errors; HTTP 401/403/500 responses treated via protocol exceptions; proxy misconfiguration; request body encoding issues; socket timeouts on large payloads.

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/7bc8c8aa0ce9ea25. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/httppost/HTTPPOST.java:325

          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, new Long( responseTime ) );
          returnFieldsOffset++;
        }
        if ( !Utils.isEmpty( meta.getResponseHeaderFieldName() ) ) {
          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, headerString );
        }
      } finally {
        // Release current connection to the connection pool once you are done
        post.releaseConnection();
        if ( httpResponse != null ) {
          httpResponse.close();
        }
      }
      return newRow;
    } catch ( UnknownHostException uhe ) {
      throw new KettleException( BaseMessages.getString( PKG,
        "HTTPPOST.Error.UnknownHostException", uhe.getMessage() ) );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "HTTPPOST.Error.CanNotReadURL", data.realUrl ), e );

    } finally {
      if ( fis != null ) {
        BaseStep.closeQuietly( fis );
      }
    }
  }

  protected int requestStatusCode( HttpResponse httpResponse ) {
    return httpResponse.getStatusLine().getStatusCode();
  }

  protected InputStreamReader openStream( String encoding, HttpResponse httpResponse ) throws Exception {
    if ( !Utils.isEmpty( encoding ) ) {
      return new InputStreamReader( httpResponse.getEntity().getContent(), encoding );
    } else {
      return new InputStreamReader( httpResponse.getEntity().getContent() );
    }

View on GitHub (pinned to f3058517a1)