{"record":{"id":"a71c3920d03fe0d4","repo":"pentaho/pentaho-kettle","slug":"ldapconnection-error-delete","errorCode":"LDAPConnection.Error.Delete","errorMessage":"LDAPConnection.Error.Delete","messagePattern":"LDAPConnection\\.Error\\.Delete","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/ldap/impl/src/main/java/org/pentaho/di/trans/steps/ldapinput/LDAPConnection.java","lineNumber":295,"sourceCode":"      if ( checkEntry ) {\n        // First Check entry\n        getInitialContext().lookup( dn );\n      }\n      // The entry exists\n      getInitialContext().destroySubcontext( dn );\n      if ( log.isDebug() ) {\n        log.logDebug( BaseMessages.getString( PKG, \"LDAPinput.Exception.Deleted\", dn ) );\n      }\n      return STATUS_DELETED;\n    } catch ( NameNotFoundException n ) {\n      // The entry is not found\n      if ( checkEntry ) {\n        throw new KettleException(\n          BaseMessages.getString( PKG, \"LDAPConnection.Error.Deleting.NameNotFound\", dn ), n );\n      }\n      return STATUS_SKIPPED;\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"LDAPConnection.Error.Delete\", dn ), e );\n    }\n  }\n\n  public int update( String dn, String[] attributes, String[] values, boolean checkEntry ) throws KettleException {\n    try {\n      int nrAttributes = attributes.length;\n      ModificationItem[] mods = new ModificationItem[nrAttributes];\n      for ( int i = 0; i < nrAttributes; i++ ) {\n        // Define attribute\n        Attribute mod = new BasicAttribute( attributes[i], values[i] );\n        if ( log.isDebug() ) {\n          log\n            .logDebug( BaseMessages.getString( PKG, \"LDAPConnection.Update.Attribute\", attributes[i], values[i] ) );\n        }\n        // Save update action on attribute\n        mods[i] = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, mod );\n      }\n      // We have all requested attribute","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/ldap/impl/src/main/java/org/pentaho/di/trans/steps/ldapinput/LDAPConnection.java#L277-L313","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconnection.delete(\"cn=\" + name + \",ou=people,dc=example,dc=com\", true);\n// after\nString safeName = name.replace(\"\\\\\", \"\\\\\\\\\").replace(\",\", \"\\\\,\");\nconnection.delete(\"cn=\" + safeName + \",ou=people,dc=example,dc=com\", true);","handlingStrategy":"try-catch","validationCode":"// Validate DN shape before deleting\njavax.naming.ldap.LdapName ln = new javax.naming.ldap.LdapName(dn); // throws InvalidNameException on malformed DN\n// and confirm the bind user's delete rights out-of-band (ACI review)","typeGuard":"boolean isValidDn(String dn) { try { new javax.naming.ldap.LdapName(dn); return true; } catch (InvalidNameException e) { return false; } }","tryCatchPattern":"try {\n  connection.delete(dn, true);\n} catch (KettleException e) {\n  Throwable root = ExceptionUtils.getRootCause(e);\n  if (root instanceof NoPermissionException) throw new KettleException(\"Bind user lacks delete rights on \" + dn, e);\n  if (root instanceof InvalidNameException) throw new KettleException(\"Malformed DN: \" + dn, e);\n  throw e;\n}","preventionTips":["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"],"tags":["ldap","kettle","delete","jndi"],"backgroundTag":"permission-denied","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"}