pentaho/pentaho-kettle · error · KettleException

AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE

AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE

Error message

AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE

What it means

AbsSecurityManager.setLogicalRoles() throws this KettleException when the underlying authorizationPolicyRoleBindingService.setRoleBindings(rolename, logicalRoles) call fails. The original exception is wrapped, so getCause() holds the real failure from the Pentaho authorization service. It means the role bindings for the named runtime role could not be persisted.

Solutions

  1. Inspect e.getCause() to find the real error from the role-binding service
  2. Confirm the rolename exists on the Pentaho server (spelling/case) and the logical role names are valid
  3. Verify the connected user has rights to modify role bindings on the server
  4. Check network connectivity / server availability and retry the setRoleBindings operation
  5. Catch the KettleException and surface a clear message to the user instead of letting the wrapped exception propagate

Example fix

// before
securityManager.setLogicalRoles("Admin", logicalRoles);
// after
try {
  securityManager.setLogicalRoles("Admin", logicalRoles);
} catch (KettleException e) {
  throw new RuntimeException("Failed to apply logical roles to role 'Admin': "
    + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()), e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate inputs before persisting role bindings
if (rolename == null || rolename.isEmpty()) {
  throw new IllegalArgumentException("rolename is required");
}
if (logicalRoles == null) {
  throw new IllegalArgumentException("logicalRoles list is required");
}

Try / catch

try {
  securityManager.setLogicalRoles(rolename, logicalRoles);
} catch (KettleException e) {
  Throwable root = e;
  while (root.getCause() != null) { root = root.getCause(); }
  throw new KettleException("setRoleBindings failed for role '" + rolename + "': " + root.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling setLogicalRoles(rolename, logicalRoles) when authorizationPolicyRoleBindingService != null but setRoleBindings throws (any Exception) — e.g. service-side rejection, network failure, or the role not existing on the server.

Common situations: Trying to map a runtime role that does not exist on the Pentaho server; server rejects the binding due to server-side permission limits of the connected user; transient connectivity problems to the Pentaho BA server; upgrading PDI/server where the role-binding API changed behavior.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/AbsSecurityManager.java:188

  public List<String> getLogicalRoles( String runtimeRole ) throws KettleException {
    if ( authorizationPolicyRoleBindingService != null ) {
      if ( roleBindingStruct != null && roleBindingStruct.bindingMap != null
          && roleBindingStruct.bindingMap.containsKey( runtimeRole ) ) {
        return roleBindingStruct.bindingMap.get( runtimeRole );
      }
      return null;
    } else {
      throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,
          "AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES" ) ); //$NON-NLS-1$
    }
  }

  public void setLogicalRoles( String rolename, List<String> logicalRoles ) throws KettleException {
    if ( authorizationPolicyRoleBindingService != null ) {
      try {
        authorizationPolicyRoleBindingService.setRoleBindings( rolename, logicalRoles );
      } catch ( Exception e ) {
        throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,
            "AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE", rolename ), e ); //$NON-NLS-1$
      }
    } else {
      throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,
          "AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES" ) ); //$NON-NLS-1$
    }
  }

  public Map<String, String> getAllLogicalRoles( String locale ) throws KettleException {
    if ( authorizationPolicyRoleBindingService != null ) {
      return roleBindingStruct.logicalRoleNameMap;
    } else {
      throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,
          "AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES" ) ); //$NON-NLS-1$
    }
  }

}

View on GitHub (pinned to f3058517a1)