pentaho/pentaho-kettle · error · SessionAuthenticationException
Unable to obtain authentication context for URL:
Error message
Unable to obtain authentication context for URL:
What it means
RepositoryCleanupUtil.authenticateLoginCredentials(), when useSessionAuth is enabled, asks SpoonSessionManager.getInstance().getAuthenticationContext(url) for the current session's AuthenticationContext; if it returns null the method throws SessionAuthenticationException "Unable to obtain authentication context for URL: ...". It means the Spoon session holds no authentication context registered for that exact URL, so login credentials cannot be validated/used for the purge repository call.
Solutions
- Log into the repository/server from the Spoon UI so an AuthenticationContext is registered, then retry the purge.
- Make the URL string exactly match the one used at login (same scheme, host, port, path).
- Switch to basic authentication (useSessionAuth=false) if a headless/scripted run has no Spoon session.
- Re-authenticate if the session expired, and normalize/validate the URL before calling the method.
Example fix
// before util.authenticateLoginCredentials( "http://localhost:8080/pentaho" ); // registered as https://server:8443 // after: reuse the exact registered URL String url = SpoonSessionManager.getInstance().getActiveRepositoryUrl(); util.authenticateLoginCredentials( url );
Defensive patterns
Strategy: validation
Validate before calling
AuthenticationContext ctx = SpoonSessionManager.getInstance().getAuthenticationContext( url );
if ( ctx == null || !ctx.isAuthenticated() ) { throw new IllegalStateException( "Log into Spoon for URL before purging: " + url ); } Try / catch
try { util.authenticateLoginCredentials( url ); } catch ( SessionAuthenticationException e ) { /* prompt re-login or fall back to basic auth */ } Prevention
- Use the exact URL string that was registered at login (scheme/host/port).
- Log in via Spoon before scripted purge operations.
- Fall back to basic auth for headless runs.
When it happens
Trigger: authenticateLoginCredentials() invoked with useSessionAuth=true and a URL for which getAuthenticationContext(url) returns null: never logged in from Spoon for that server, the URL string differs (scheme/host/port/trailing slash) from the one registered at login, or the session context expired/was cleared.
Common situations: Running a purge against a URL slightly different from the one used to log in (http vs https, hostname vs IP, port mismatch); attempting purge before logging into the repository through the Spoon UI; session invalidated after idle timeout; testing session auth in headless/scripted environments where no Spoon session exists.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Session-based authentication is enabled but no valid…
- Attempting to create PDI Repository with no Active…
- Auth error
- Browser session authentication requested but no JSESSIONID…
- CmsTokenProvider: Keycloak token request failed — HTTP
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a991cdf8ff2d1481.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/pur/core/src/main/java/com/pentaho/di/purge/RepositoryCleanupUtil.java:373
@VisibleForTesting
void authenticateLoginCredentials() throws Exception {
KettleClientEnvironment.init();
if ( client == null ) {
ClientConfig clientConfig = new ClientConfig();
clientConfig.property( ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE );
client = ClientBuilder.newClient( clientConfig );
// Check if session-based authentication is enabled
final boolean useSessionAuth = AuthenticationContext.SESSION_AUTH_TOKEN.equals( password );
if ( useSessionAuth ) {
// Get authentication context using the factory pattern
AuthenticationContext authContext =
SpoonSessionManager.getInstance().getAuthenticationContext( url );
if ( authContext == null ) {
throw new SessionAuthenticationException(
"Unable to obtain authentication context for URL: " + url
+ ". Verify the URL is valid and properly formatted." );
}
// Check if authenticated
if ( authContext.isAuthenticated() ) {
String jsessionId = authContext.getJSessionId();
// Register a ClientRequestFilter to add Cookie header to every request
final String finalJsessionId = jsessionId;
client.register( (jakarta.ws.rs.client.ClientRequestFilter) requestContext ->
requestContext.getHeaders().add( "Cookie", "JSESSIONID=" + finalJsessionId )
);
} else {
throw new SessionAuthenticationException( "Session-based authentication is enabled but no valid session found. Please authenticate through browser first." );
}
} else {
// Use basic authentication with username/passwordView on GitHub (pinned to f3058517a1)