{"record":{"id":"c7df62ff7d080655","repo":"pentaho/pentaho-kettle","slug":"httppost-exception-authentication","errorCode":"HTTPPOST.Exception.Authentication","errorMessage":"HTTPPOST.Exception.Authentication","messagePattern":"HTTPPOST\\.Exception\\.Authentication","errorType":"exception","errorClass":"KettleStepException","httpStatus":401,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/httppost/HTTPPOST.java","lineNumber":255,"sourceCode":"        int statusCode = requestStatusCode( httpResponse );\n\n        // calculate the responseTime\n        long responseTime = System.currentTimeMillis() - startTime;\n\n        if ( isDetailed() ) {\n          logDetailed( BaseMessages.getString( PKG, \"HTTPPOST.Log.ResponseTime\", responseTime, data.realUrl ) );\n        }\n\n        // Display status code\n        if ( isDebug() ) {\n          logDebug( BaseMessages.getString( PKG, \"HTTPPOST.Log.ResponseCode\", String.valueOf( statusCode ) ) );\n        }\n\n        String body;\n        String headerString = \"\";\n        switch ( statusCode ) {\n          case HttpURLConnection.HTTP_UNAUTHORIZED:\n            throw new KettleStepException( BaseMessages\n              .getString( PKG, \"HTTPPOST.Exception.Authentication\", data.realUrl ) );\n          case -1:\n            throw new KettleStepException( BaseMessages\n              .getString( PKG, \"HTTPPOST.Exception.IllegalStatusCode\", data.realUrl ) );\n          case HttpURLConnection.HTTP_NO_CONTENT:\n            body = \"\";\n            break;\n          default:\n            HttpEntity entity = httpResponse.getEntity();\n            if ( entity != null ) {\n              body = EntityUtils.toString( entity );\n            } else {\n              body = \"\";\n            }\n            Header[] headers = searchForHeaders( httpResponse );\n            // Use request encoding if specified in component to avoid strange response encodings\n            // See PDI-3815\n","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/httppost/HTTPPOST.java#L237-L273","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npostMethod.setAuth( false ); // no credentials sent, server returns 401\n// after\nmeta.setLogin( \"apiUser\" );\nmeta.setPassword( Encr.decryptPasswordOptionallyEncrypted( \"${API_PASSWORD}\" ) );\nmeta.setPreemptive( true );","handlingStrategy":"try-catch","validationCode":"// pre-flight: confirm credentials work before running the transformation\ncurl -s -o /dev/null -w '%{http_code}' -u user:pass https://host/api  # expect 200/204, not 401","typeGuard":null,"tryCatchPattern":"try { outputRowData = callHTTPPOST( ... ); } catch ( KettleStepException e ) {\n  if ( e.getMessage().contains( \"Authentication\" ) ) {\n    logError( \"401 from \" + url + \": check credentials/token\" );\n    // refresh token and retry once, else route row to error stream\n  } else throw e;\n}","preventionTips":["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"],"tags":["http","authentication","http-401","kettle"],"backgroundTag":"authentication-required","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}