{"record":{"id":"86a022e78e21d51a","repo":"pentaho/pentaho-kettle","slug":"abssecuritymanager-error-0004-unable-to-apply-logical-roles","errorCode":"AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE","errorMessage":"AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE","messagePattern":"AbsSecurityManager\\.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE","errorType":"error_code","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/AbsSecurityManager.java","lineNumber":188,"sourceCode":"  public List<String> getLogicalRoles( String runtimeRole ) throws KettleException {\n    if ( authorizationPolicyRoleBindingService != null ) {\n      if ( roleBindingStruct != null && roleBindingStruct.bindingMap != null\n          && roleBindingStruct.bindingMap.containsKey( runtimeRole ) ) {\n        return roleBindingStruct.bindingMap.get( runtimeRole );\n      }\n      return null;\n    } else {\n      throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,\n          \"AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES\" ) ); //$NON-NLS-1$\n    }\n  }\n\n  public void setLogicalRoles( String rolename, List<String> logicalRoles ) throws KettleException {\n    if ( authorizationPolicyRoleBindingService != null ) {\n      try {\n        authorizationPolicyRoleBindingService.setRoleBindings( rolename, logicalRoles );\n      } catch ( Exception e ) {\n        throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,\n            \"AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE\", rolename ), e ); //$NON-NLS-1$\n      }\n    } else {\n      throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,\n          \"AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES\" ) ); //$NON-NLS-1$\n    }\n  }\n\n  public Map<String, String> getAllLogicalRoles( String locale ) throws KettleException {\n    if ( authorizationPolicyRoleBindingService != null ) {\n      return roleBindingStruct.logicalRoleNameMap;\n    } else {\n      throw new KettleException( BaseMessages.getString( AbsSecurityManager.class,\n          \"AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES\" ) ); //$NON-NLS-1$\n    }\n  }\n\n}","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/AbsSecurityManager.java#L170-L206","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect e.getCause() to find the real error from the role-binding service","Confirm the rolename exists on the Pentaho server (spelling/case) and the logical role names are valid","Verify the connected user has rights to modify role bindings on the server","Check network connectivity / server availability and retry the setRoleBindings operation","Catch the KettleException and surface a clear message to the user instead of letting the wrapped exception propagate"],"exampleFix":"// before\nsecurityManager.setLogicalRoles(\"Admin\", logicalRoles);\n// after\ntry {\n  securityManager.setLogicalRoles(\"Admin\", logicalRoles);\n} catch (KettleException e) {\n  throw new RuntimeException(\"Failed to apply logical roles to role 'Admin': \"\n    + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()), e);\n}","handlingStrategy":"try-catch","validationCode":"// Validate inputs before persisting role bindings\nif (rolename == null || rolename.isEmpty()) {\n  throw new IllegalArgumentException(\"rolename is required\");\n}\nif (logicalRoles == null) {\n  throw new IllegalArgumentException(\"logicalRoles list is required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  securityManager.setLogicalRoles(rolename, logicalRoles);\n} catch (KettleException e) {\n  Throwable root = e;\n  while (root.getCause() != null) { root = root.getCause(); }\n  throw new KettleException(\"setRoleBindings failed for role '\" + rolename + \"': \" + root.getMessage(), e);\n}","preventionTips":["Verify the runtime role exists on the server (exact name/case) before setting bindings","Confirm the connected user has server-side rights to modify role bindings","Always unwrap getCause() to diagnose the real service failure","Retry on transient connectivity errors to the Pentaho server"],"tags":["kettle","pentaho","role-bindings","wrapped-exception"],"backgroundTag":"api-request-failed","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"}