pentaho/pentaho-kettle · error · KettleException
LDAPConnection.Error.Delete
LDAPConnection.Error.Delete
Error message
LDAPConnection.Error.Delete
What it means
LDAPConnection.delete(dn, checkEntry) wraps any non-NameNotFound exception from the JNDI delete in a KettleException with message key 'LDAPConnection.Error.Delete' (dn interpolated). Typical causes are insufficient permissions, invalid DN syntax, or connectivity/schema constraints — the raw javax.naming exception is attached as cause.
Solutions
- Read e.getCause() (e.g. InvalidNameException, NoPermissionException) and fix the DN or permissions accordingly.
- Escape special characters in DN values (',' '+' '"' '\\' '<' '>' ';') or use LdapName/ldapsearch to validate.
- Grant the bind user delete permission on the target subtree, or bind with an admin/service account.
- Delete child entries before deleting a parent, if the directory requires leaf deletion.
Example fix
// before
connection.delete("cn=" + name + ",ou=people,dc=example,dc=com", true);
// after
String safeName = name.replace("\\", "\\\\").replace(",", "\\,");
connection.delete("cn=" + safeName + ",ou=people,dc=example,dc=com", true); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate DN shape before deleting javax.naming.ldap.LdapName ln = new javax.naming.ldap.LdapName(dn); // throws InvalidNameException on malformed DN // and confirm the bind user's delete rights out-of-band (ACI review)
Type guard
boolean isValidDn(String dn) { try { new javax.naming.ldap.LdapName(dn); return true; } catch (InvalidNameException e) { return false; } } Try / catch
try {
connection.delete(dn, true);
} catch (KettleException e) {
Throwable root = ExceptionUtils.getRootCause(e);
if (root instanceof NoPermissionException) throw new KettleException("Bind user lacks delete rights on " + dn, e);
if (root instanceof InvalidNameException) throw new KettleException("Malformed DN: " + dn, e);
throw e;
} Prevention
- Escape ',', '+', '"', '\\', '<', '>' in DN values built from user data
- Bind with an account that has explicit delete permissions on the subtree
- Delete child entries before parents when the directory requires it
- Pre-check DNs with LdapName parsing before issuing deletes
When it happens
Trigger: Calling delete() with a malformed DN string, a DN containing unescaped special characters, while bound as a user without delete rights on the entry, or when the server refuses deletion of entries that still have children.
Common situations: DN values from CSV/database fields containing unescaped commas or slashes; bind account lacking ACI/ACL delete permission; attempting to delete a non-leaf entry on directories that forbid it; SSL/TLS handshake failure mid-operation.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- LDAPConnection.Error.Deleting.NameNotFound
- LDAPConnection.Error.Insert
- LDAPConnection.Error.Search
- LDAPConnection.Error.Update
- LDAPConnection.Error.Upsert
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a71c3920d03fe0d4.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/ldap/impl/src/main/java/org/pentaho/di/trans/steps/ldapinput/LDAPConnection.java:295
if ( checkEntry ) {
// First Check entry
getInitialContext().lookup( dn );
}
// The entry exists
getInitialContext().destroySubcontext( dn );
if ( log.isDebug() ) {
log.logDebug( BaseMessages.getString( PKG, "LDAPinput.Exception.Deleted", dn ) );
}
return STATUS_DELETED;
} catch ( NameNotFoundException n ) {
// The entry is not found
if ( checkEntry ) {
throw new KettleException(
BaseMessages.getString( PKG, "LDAPConnection.Error.Deleting.NameNotFound", dn ), n );
}
return STATUS_SKIPPED;
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "LDAPConnection.Error.Delete", dn ), e );
}
}
public int update( String dn, String[] attributes, String[] values, boolean checkEntry ) throws KettleException {
try {
int nrAttributes = attributes.length;
ModificationItem[] mods = new ModificationItem[nrAttributes];
for ( int i = 0; i < nrAttributes; i++ ) {
// Define attribute
Attribute mod = new BasicAttribute( attributes[i], values[i] );
if ( log.isDebug() ) {
log
.logDebug( BaseMessages.getString( PKG, "LDAPConnection.Update.Attribute", attributes[i], values[i] ) );
}
// Save update action on attribute
mods[i] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, mod );
}
// We have all requested attributeView on GitHub (pinned to f3058517a1)