pentaho/pentaho-kettle · error · SessionAuthenticationException

Session-based authentication is enabled but no valid…

Error message

Session-based authentication is enabled but no valid session found. Please authenticate through browser first.

What it means

This error is thrown by RepositoryCleanupUtil.authenticateLoginCredentials when session-based authentication is enabled for the purge client but no valid JSESSIONID browser session is available. Instead of registering a basic-auth HttpAuthenticationFeature, the utility registers a ClientRequestFilter that adds a 'Cookie: JSESSIONID=<jsessionId>' header to every request; when jsessionId is null/blank it refuses to proceed and throws SessionAuthenticationException.

Solutions

  1. Log into the Pentaho web console in a browser first to obtain a valid JSESSIONID, then re-run with session auth enabled
  2. Switch to basic authentication mode so HttpAuthenticationFeature.basic(username, decryptedPassword) is registered instead of requiring a session cookie
  3. Verify the jsessionId configuration/property is populated and current (not an expired session)
  4. For headless automation, configure basic auth credentials or capture a fresh JSESSIONID programmatically before invoking purge

Example fix

// before: session auth with missing cookie
throw new SessionAuthenticationException( "Session-based authentication is enabled but no valid session found..." );
// after: fall back to basic auth when no session is present
if ( sessionAuthEnabled && jsessionId != null && !jsessionId.isBlank() ) {
  client.register( (jakarta.ws.rs.client.ClientRequestFilter) ctx -> ctx.getHeaders().add( "Cookie", "JSESSIONID=" + jsessionId ) );
} else if ( username != null && password != null ) {
  client.register( HttpAuthenticationFeature.basic( username, Encr.decryptPasswordOptionallyEncrypted( password ) ) );
} else {
  throw new SessionAuthenticationException( "..." );
}
Defensive patterns

Strategy: validation

Validate before calling

if ( sessionAuthEnabled && ( jsessionId == null || jsessionId.isBlank() ) ) {
  throw new IllegalStateException( "Session auth enabled but no JSESSIONID; log into the Pentaho console first or configure basic auth." );
}

Type guard

boolean hasValidSession( String jsessionId ) { return jsessionId != null && !jsessionId.isBlank(); }

Try / catch

try {
  purgeUtil.authenticateLoginCredentials( client, username, password, useSessionAuth, jsessionId );
} catch ( SessionAuthenticationException e ) {
  log.error( "No valid browser session; falling back to basic auth or prompting login", e );
  registerBasicAuthOrPrompt();
}

Prevention

When it happens

Trigger: Calling purge(), authenticateLoginCredentials(), or the test wrappers when session authentication mode is enabled and the resolved jsessionId is null or empty, so the else branch at line 388 throws SessionAuthenticationException.

Common situations: Running the purge utility against a Pentaho repository where session auth was selected but the user never logged into the Pentaho web console (no browser session cookie captured); an expired JSESSIONID supplied via configuration; automated/headless runs with no interactive browser login available.

Understand the failure class

Related errors


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

Appendix: source

Thrown at plugins/pur/core/src/main/java/com/pentaho/di/purge/RepositoryCleanupUtil.java:388

          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/password
        HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic( username, Encr.decryptPasswordOptionallyEncrypted( password ) );
        client.register( feature );
      }
    }

    WebTarget target = client.target( url + AUTHENTICATION + AdministerSecurityAction.NAME );
    String response = target.request( MediaType.TEXT_PLAIN ).get( String.class );

    if ( !response.equals( "true" ) ) {
      throw new Exception( Messages.getInstance().getString( "REPOSITORY_CLEANUP_UTIL.ERROR_0012.ACCESS_DENIED" ) );
    }
  }

  /**
   * Create URL to access REST API based on provided parameters

View on GitHub (pinned to f3058517a1)