pentaho/pentaho-kettle · error · KettleException

PurRepository.LoginException.Message

PurRepository.LoginException.Message

Error message

PurRepository.LoginException.Message (localized; login failed due to unexpected error)

What it means

PurRepositoryConnector.connect treats a NullPointerException during repository connection setup as a fatal, unexplained login failure and throws a localized KettleException (PurRepository.LoginException.Message). The NPE is swallowed, so the actual cause (often a missing service/config) is hidden. This is a defensive catch-all inside the connect routine.

Solutions

  1. Verify the repository connection definition (URL, username, password) is complete and correct
  2. Ensure the Pentaho server/BIServer context is initialized and reachable before connecting
  3. Get the underlying NPE: enable debug logging or step through connect() since the exception text hides the cause
  4. Call connect with a valid session/auth context (the session-auth tests show null/empty contexts throw here)

Example fix

// before
PurRepositoryDefinition def = new PurRepositoryDefinition(); // fields unset
repository.connect(pmeta);
// after
if (pmeta.getRepositoryConnectionUser() == null || pmeta.getRepositoryConnectionUrl() == null) {
  throw new KettleException("Repository URL and user must be set before connecting");
}
repository.connect(pmeta);
Defensive patterns

Strategy: validation

Validate before calling

if (repoMeta == null || repoMeta.getRepositoryConnectionUrl() == null
    || repoMeta.getRepositoryConnectionUser() == null
    || repoMeta.getRepositoryConnectionPassword() == null) {
  throw new KettleException("Incomplete PUR connection settings");
}

Try / catch

try {
  repository.connect(repoMeta);
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("login")) {
    log.error("PUR login failed (possible NPE in connect); check connection config and server context", e);
  } else throw e;
}

Prevention

When it happens

Trigger: connect() internally throws NPE anywhere between initialization and registerRepositoryServices — e.g. repository metadata null, uninitialized PentahoSystem/registry, or missing decryption result — caught by the dedicated catch (NullPointerException npe) branch.

Common situations: Connecting to a PUR repository with incomplete connection settings (missing server URL/user); the BI Platform context not being initialized so PentahoSystem lookups return null; testing connections from unit tests without a live server (see the testConnectWithSessionAuth_* tests).

Related errors


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

Appendix: source

Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepositoryConnector.java:147

      RepositoryConnectResult inProcessResult = tryInProcessConnect( decryptedPassword, result );
      if ( inProcessResult != null ) {
        return inProcessResult;
      }

      ExecutorService executor = getExecutor();
      Future<Boolean> authorizationFuture = buildAuthorizationFuture( executor, result );
      Future<WebServiceException> repoFuture = buildRepoWebServiceFuture( executor, username, decryptedPassword, result );
      Future<Exception> syncFuture = buildSyncWebServiceFuture( executor, username, decryptedPassword, result );
      Future<String> sessionFuture = buildSessionServiceFuture( executor, username, decryptedPassword, useSessionAuth );

      applyFutureResults( result, authorizationFuture, repoFuture, syncFuture, sessionFuture );

      registerRepositoryServices( purRepositoryServiceRegistry, username, decryptedPassword, result );

      result.setSuccess( true );
    } catch ( NullPointerException npe ) {
      result.setSuccess( false );
      throw new KettleException( BaseMessages.getString( PKG, "PurRepository.LoginException.Message" ) );
    } catch ( InterruptedException ie ) {
      result.setSuccess( false );
      serviceManager.close();
      Thread.currentThread().interrupt();
      throw new KettleException( ie );
    } catch ( Exception e ) {
      result.setSuccess( false );
      serviceManager.close();
      throw new KettleException( e );
    }
    return result;
  }

  /**
   * Validates that a JSESSIONID is available when session-based authentication is requested.
   *
   * @throws KettleException if no valid JSESSIONID can be found
   */

View on GitHub (pinned to f3058517a1)