pentaho/pentaho-kettle · error · KettleStepException

HTTPPOST.Exception.IllegalStatusCode

HTTPPOST.Exception.IllegalStatusCode

Error message

HTTPPOST.Exception.IllegalStatusCode

What it means

The HTTP POST step got a response with no valid status line (statusCode == -1), which the step treats as an illegal/unknown status and throws KettleStepException 'HTTPPOST.Exception.IllegalStatusCode' naming the URL. This usually indicates the connection failed before a real HTTP response arrived or the response was not valid HTTP.

Solutions

  1. Check connectivity to the host/port and confirm the protocol scheme (http vs https) matches the server.
  2. Inspect server/proxy logs around the request time for resets or dropped connections.
  3. Retry the request; transient network failures commonly surface as status -1.
  4. Capture the raw response with curl or tcpdump to see what the endpoint actually returns.
  5. Ensure any proxy in front of the service is configured to pass through valid HTTP responses.

Example fix

// before
String url = "http://secure.example.com/api"; // server is HTTPS-only, response is not valid HTTP
// after
String url = "https://secure.example.com/api";
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: ensure the endpoint answers with a valid HTTP status before running
curl -s -o /dev/null -w '%{http_code}' --max-time 10 https://host/api  # must return a numeric HTTP code

Try / catch

try { outputRowData = callHTTPPOST( ... ); } catch ( KettleStepException e ) {
  if ( e.getMessage().contains( "IllegalStatusCode" ) ) {
    logError( "No valid HTTP status from " + url + "; check scheme/proxy/server health" );
    // retry with backoff or send row to error stream
  } else throw e;
}

Prevention

When it happens

Trigger: callHTTPPOST switch on statusCode hits case -1 — the HTTP method executed but produced no status code (connection reset, malformed/non-HTTP response, connection closed prematurely by server or proxy).

Common situations: Server closing the connection before responding; a proxy or load balancer returning a non-HTML garbage response; HTTPS endpoint hit with http:// (or vice versa) yielding a protocol error; server crash mid-request.

Related errors


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

Appendix: source

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

        long responseTime = System.currentTimeMillis() - startTime;

        if ( isDetailed() ) {
          logDetailed( BaseMessages.getString( PKG, "HTTPPOST.Log.ResponseTime", responseTime, data.realUrl ) );
        }

        // Display status code
        if ( isDebug() ) {
          logDebug( BaseMessages.getString( PKG, "HTTPPOST.Log.ResponseCode", String.valueOf( statusCode ) ) );
        }

        String body;
        String headerString = "";
        switch ( statusCode ) {
          case HttpURLConnection.HTTP_UNAUTHORIZED:
            throw new KettleStepException( BaseMessages
              .getString( PKG, "HTTPPOST.Exception.Authentication", data.realUrl ) );
          case -1:
            throw new KettleStepException( BaseMessages
              .getString( PKG, "HTTPPOST.Exception.IllegalStatusCode", data.realUrl ) );
          case HttpURLConnection.HTTP_NO_CONTENT:
            body = "";
            break;
          default:
            HttpEntity entity = httpResponse.getEntity();
            if ( entity != null ) {
              body = EntityUtils.toString( entity );
            } else {
              body = "";
            }
            Header[] headers = searchForHeaders( httpResponse );
            // Use request encoding if specified in component to avoid strange response encodings
            // See PDI-3815

            JSONObject json = new JSONObject();
            for ( Header header : headers ) {
              Object previousValue = json.get( header.getName() );

View on GitHub (pinned to f3058517a1)