{"record":{"id":"3eb0674b34031626","repo":"pentaho/pentaho-kettle","slug":"session-expired","errorCode":null,"errorMessage":"Session expired","messagePattern":"Session expired","errorType":"exception","errorClass":"KettleAuthenticationException","httpStatus":null,"severity":"error","filePath":"plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/UnifiedRepositoryInvocationHandler.java","lineNumber":43,"sourceCode":"\nclass UnifiedRepositoryInvocationHandler<T> implements InvocationHandler {\n  private T rep;\n\n\n  UnifiedRepositoryInvocationHandler( T rep ) {\n    this.rep = rep;\n  }\n\n  @Override\n  public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable {\n    try {\n      return method.invoke( rep, args );\n    } catch ( InvocationTargetException ex ) {\n      // Check authentication errors FIRST - session expiry must be detected immediately\n      if ( lookupAuthenticationException( ex ) ) {\n        // DO NOT close web services here\n        // DO NOT retry\n        throw new KettleAuthenticationException( \"Session expired\", ex.getCause() );\n      }\n\n      if ( lookupConnectException( ex ) ) {\n        throw new KettleRepositoryLostException( ex.getCause() );\n      }\n\n      throw ex.getCause();\n    }\n  }\n\n  private boolean lookupConnectException( Throwable root ) {\n    while ( root != null ) {\n      if ( root instanceof ConnectException ) {\n        return true;\n      } else {\n        root = root.getCause();\n      }\n    }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/UnifiedRepositoryInvocationHandler.java#L25-L61","documentation":"UnifiedRepositoryInvocationHandler.invoke wraps every call to the unified repository proxy. When the underlying invocation throws an InvocationTargetException caused by an authentication failure (session expired/invalid), it converts it to KettleAuthenticationException(\"Session expired\"). This surfaces server-side session loss as a typed exception so callers can re-authenticate.","triggerScenarios":"Any repository operation (get, save, delete, list) executed through the proxy after the server HTTP session or auth token expired, or when the server rejects the credentials/session cookie.","commonSituations":"Long-running jobs whose session timed out mid-run, server restart invalidating sessions, load balancer failing to pin sessions, or shared repository connections left idle beyond the session timeout.","solutions":["Reconnect/re-authenticate to the repository (re-call repository.connect with valid credentials) and retry the operation.","Catch KettleAuthenticationException and implement a re-login-and-retry wrapper around repository calls.","Increase the Pentaho server session timeout or keep the connection alive with periodic activity.","Verify the server is not restarting / the load balancer preserves session affinity."],"exampleFix":"// before\nRepositoryFile file = pur.getFileById( id ); // throws KettleAuthenticationException on expired session\n// after\nRepositoryFile file;\ntry {\n  file = pur.getFileById( id );\n} catch ( KettleAuthenticationException e ) {\n  repository.disconnect();\n  repository.connect( username, password ); // re-authenticate\n  file = pur.getFileById( id );\n}","handlingStrategy":"retry","validationCode":"boolean sessionLikelyValid() {\n  try { pur.getRepositoryMeta(); return true; } catch ( KettleAuthenticationException e ) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return rep.call( args );\n} catch ( KettleAuthenticationException e ) {\n  repository.disconnect();\n  repository.connect( user, pass );\n  return rep.call( args ); // retry once after re-auth\n}","preventionTips":["Wrap long-running repository work in a re-login-and-retry helper","Increase server session timeout for long jobs","Ping the repository periodically during idle periods","Ensure load balancer session affinity for Pentaho server"],"tags":["authentication","session","pentaho-kettle"],"backgroundTag":"jwt-token-expired","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"}