pentaho/pentaho-kettle · error · KettleStepException

HTTPPOST.Exception.Authentication

HTTPPOST.Exception.Authentication

Error message

HTTPPOST.Exception.Authentication

What it means

The HTTP POST step received HTTP 401 Unauthorized from the target server. callHTTPPOST maps status code HttpURLConnection.HTTP_UNAUTHORIZED (401) to a KettleStepException 'HTTPPOST.Exception.Authentication' naming the requested URL.

Solutions

  1. Verify login/password (or pre-emptive auth settings) in the HTTP POST step's Authentication tab.
  2. If the API expects a Bearer token, disable basic auth and add an 'Authorization: Bearer ...' HTTP header.
  3. Test the credentials with curl against the same URL to confirm they are valid.
  4. Check that environment variables substituted into credentials resolve to current values.

Example fix

// before
postMethod.setAuth( false ); // no credentials sent, server returns 401
// after
meta.setLogin( "apiUser" );
meta.setPassword( Encr.decryptPasswordOptionallyEncrypted( "${API_PASSWORD}" ) );
meta.setPreemptive( true );
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: confirm credentials work before running the transformation
curl -s -o /dev/null -w '%{http_code}' -u user:pass https://host/api  # expect 200/204, not 401

Try / catch

try { outputRowData = callHTTPPOST( ... ); } catch ( KettleStepException e ) {
  if ( e.getMessage().contains( "Authentication" ) ) {
    logError( "401 from " + url + ": check credentials/token" );
    // refresh token and retry once, else route row to error stream
  } else throw e;
}

Prevention

When it happens

Trigger: The HTTP POST request completes and the server returns status 401 — credentials missing, wrong, or expired, or the auth scheme (Basic/Digest/NTLM/OAuth) is not correctly configured for data.realUrl.

Common situations: Forgotten username/password in the step's Authentication tab; wrong password after rotation; server requires a token/Bearer header that was never added as an HTTP header; proxy intercepting and challenging the request.

Understand the failure class

Related errors


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

Appendix: source

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

        int statusCode = requestStatusCode( httpResponse );

        // calculate the responseTime
        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

View on GitHub (pinned to f3058517a1)