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
- Read e.getCause(): NameAlreadyBoundException means the new DN exists — choose a unique new DN or delete/move the conflicting entry.
- Ensure the target parent OU exists before renaming.
- Grant the bind account rename (moddn) and delete rights on both source and target subtrees.
- For subtrees, verify no leftover children from a previous failed rename and rename leaves first.
- 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
- Uniqueness-check the new DN before renaming
- Grant 'Modify RDN'/moddn and delete rights on both subtrees
- Handle subtree renames carefully: rename children leaves-first and clean leftovers from failed runs
- Verify the directory supports moves across OUs (some proxies/embedded servers do not)
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
- It's not possible to rename Class [" +…
- LDAPConnection.Error.Add
- LDAPConnection.Error.Delete
- LDAPConnection.Error.Deleting.NameNotFound
- LDAPConnection.Error.Insert
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)