pentaho/pentaho-kettle · error · KettleException

LDAPConnection.Error.Renaming

LDAPConnection.Error.Renaming

Error message

LDAPConnection.Error.Renaming

What it means

LDAPConnection.rename(oldDn, newDn, ...) wraps any exception from the JNDI rename/createSubcontext sequence in a KettleException with message key 'LDAPConnection.Error.Renaming' (oldDn and newDn interpolated). It fails when the source DN doesn't exist, the new DN already exists, the new parent is missing, the directory lacks MODDN support, or the bind user lacks modify-RDN/rename permission.

Solutions

  1. Read e.getCause(): NameAlreadyBoundException means the new DN exists — choose a unique new DN or delete/move the conflicting entry.
  2. Ensure the target parent OU exists before renaming.
  3. Grant the bind account rename (moddn) and delete rights on both source and target subtrees.
  4. For subtrees, verify no leftover children from a previous failed rename and rename leaves first.
  5. Test the rename manually with ldapmoddn/ldp.exe before running the transformation.

Example fix

// before
connection.rename("cn=jsmith,ou=people,dc=example,dc=com", "cn=smith,ou=people,dc=example,dc=com", true, false);
// after (ensure uniqueness of the new RDN first)
if (!dnExists(connection, "cn=smith,ou=people,dc=example,dc=com")) {
  connection.rename("cn=jsmith,ou=people,dc=example,dc=com", "cn=smith,ou=people,dc=example,dc=com", true, false);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: source exists and target is free
boolean sourceExists = dnExists(connection, oldDn);
boolean targetFree = !dnExists(connection, newDn);
if (!sourceExists || !targetFree) throw new KettleException("Rename pre-check failed for " + oldDn + " -> " + newDn);

Try / catch

try {
  connection.rename(oldDn, newDn, true, false);
} catch (KettleException e) {
  Throwable root = ExceptionUtils.getRootCause(e);
  if (root instanceof NameAlreadyBoundException) { /* new DN taken: pick unique RDN or clean up */ }
  else if (root instanceof OperationNotSupportedException) { /* server lacks moddn/move support */ }
  else if (root instanceof NoPermissionException) { /* grant moddn/delete rights */ }
  throw e;
}

Prevention

When it happens

Trigger: Renaming to a DN that already exists; moving entries across subtrees when the new parent OU doesn't exist or moddn ( ldap rename) is restricted; renaming entries with children on servers that only support leaf renames; the deleteRDN environment handling failing in the finally block.

Common situations: Reorganizing an OU structure on AD where the target CN already exists; bind account missing 'Modify RDN'/'Delete Child' rights; renaming on proxies/embedded directories without full moddn support; leftover temporary child entries from a prior failed rename blocking the re-create of subtree children.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at plugins/ldap/impl/src/main/java/org/pentaho/di/trans/steps/ldapinput/LDAPConnection.java:494

        // re attached removed sub contexts
        for ( int i = paths.size(); i > 0; i-- ) {
          getInitialContext().createSubcontext( paths.get( i - 1 ), childs.get( paths.get( i - 1 ) ) );
        }
        throw e;
      }

      // attach sub context
      List<String> newpaths = new ArrayList<String>();
      for ( String childName : paths ) {
        newpaths.add( childName.replaceAll( oldDn, newDn ) );
      }

      for ( int i = newpaths.size(); i > 0; i-- ) {
        getInitialContext().createSubcontext( newpaths.get( i - 1 ), childs.get( paths.get( i - 1 ) ) );
      }

    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "LDAPConnection.Error.Renaming", oldDn, newDn ), e );
    } finally {
      try {
        if ( !deleteRDN ) {
          // Delete the old dn as attribute
          // switch back to default value
          getInitialContext().addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
        }
      } catch ( Exception e ) {
        // Ignore errors
      }
    }

  }

  @SuppressWarnings( "rawtypes" )
  private void getPaths( String rootName, Map<String, Attributes> childs, List<String> paths ) throws Exception {
    NamingEnumeration ne = getInitialContext().list( rootName );
    while ( ne.hasMore() ) {

View on GitHub (pinned to f3058517a1)