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
- Verify login/password (or pre-emptive auth settings) in the HTTP POST step's Authentication tab.
- If the API expects a Bearer token, disable basic auth and add an 'Authorization: Bearer ...' HTTP header.
- Test the credentials with curl against the same URL to confirm they are valid.
- 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
- Store credentials as encrypted variables, rotate them before expiry
- Prefer Bearer-token headers for APIs that do not accept Basic auth
- Test credentials with curl from the same host as the Pentaho server
- Enable pre-emptive authentication when the server does not issue a challenge
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- HTTP.Exception.Authentication
- Auth error
- Browser session authentication requested but no JSESSIONID…
- CmsTokenProvider: Keycloak token request failed — HTTP
- HTTP.Error.UnknownHostException
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)