pentaho/pentaho-kettle · error · KettleException
LDAPConnection.Error.Upsert
LDAPConnection.Error.Upsert
Error message
LDAPConnection.Error.Upsert
What it means
LDAPConnection.upsert(dn, attributesToUpdate, valuesToUpdate, multValuedSeparator) performs a lookup of the DN and either adds it (createSubcontext) or replaces its attributes (modifyAttributes REPLACE_ATTRIBUTE). Any exception in either path is wrapped in a KettleException with message key 'LDAPConnection.Error.Upsert' (dn interpolated), with the JNDI exception as cause.
Solutions
- Inspect e.getCause() to tell whether the failure was on the insert or the modify path.
- Ensure the parent OU exists before upserting new entries.
- Verify bind account has both create and write rights on the target subtree.
- Validate attributes/values against the objectClass schema (required and allowed attributes).
- Escape DN special characters before calling upsert.
Example fix
// before connection.upsert(dn, attrs, vals, ";"); // parent OU may not exist // after ensureOuDExists(connection, "ou=people,dc=example,dc=com"); connection.upsert(dn, attrs, vals, ";");
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: verify parent OU and bind account rights
String parentDn = dn.substring(dn.indexOf(",") + 1);
connection.setSearchBase(parentDn);
connection.setFilter("(objectClass=*)");
connection.search(); // empty => parent OU missing, create it before upsert Try / catch
try {
connection.upsert(dn, attrs, vals, ";");
} catch (KettleException e) {
Throwable root = ExceptionUtils.getRootCause(e);
if (root instanceof NoPermissionException) { /* grant create+write rights */ }
else if (root instanceof SchemaViolationException) { /* fix attributes vs objectClass */ }
throw e;
} Prevention
- Ensure the bind account has BOTH create and modify rights (upsert uses either path)
- Create parent OUs before running upserts against new subtrees
- Validate attribute/value syntax against the schema
- Log the root cause to distinguish insert-path vs update-path failures
When it happens
Trigger: Upsert where the parent OU for a new entry doesn't exist; replace on a DN whose attributes violate schema; permission failures on create or modify; connection/authentication loss; invalid DN syntax.
Common situations: Mixed create/update runs where the bind account can modify but not create (or vice versa); mandatory objectClass attributes missing on insert path; single-valued attribute receiving multiple values on replace.
Related errors
- LDAPConnection.Error.Delete
- LDAPConnection.Error.Insert
- LDAPConnection.Error.Search
- LDAPConnection.Error.Update
- LDAPConnection.Error.Add
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/ade91d35a3f2cd9c.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/ldap/impl/src/main/java/org/pentaho/di/trans/steps/ldapinput/LDAPConnection.java:417
try {
getInitialContext().getAttributes( dn );
found = true;
} catch ( NameNotFoundException n ) {
Attributes attrs = buildAttributes( dn, attributes, values, multValuedSeparator );
getInitialContext().createSubcontext( dn, attrs );
return STATUS_INSERTED;
}
if ( found && attributesToUpdate != null && attributesToUpdate.length > 0 ) {
// The entry already exist
// let's update
Attributes attrs = buildAttributes( dn, attributesToUpdate, valuesToUpdate, multValuedSeparator );
getInitialContext().modifyAttributes( dn, DirContext.REPLACE_ATTRIBUTE, attrs );
return STATUS_UPDATED;
}
} catch ( Exception e ) {
throw new KettleException( BaseMessages.getString( PKG, "LDAPConnection.Error.Upsert", dn ), e );
}
return STATUS_SKIPPED;
}
private Attributes buildAttributes( String dn, String[] attributes, String[] values, String multValuedSeparator ) {
Attributes attrs = new javax.naming.directory.BasicAttributes( true );
int nrAttributes = attributes.length;
for ( int i = 0; i < nrAttributes; i++ ) {
if ( !Utils.isEmpty( values[i] ) ) {
// We have a value
String value = values[i].trim();
if ( multValuedSeparator != null && value.indexOf( multValuedSeparator ) > 0 ) {
Attribute attr = new javax.naming.directory.BasicAttribute( attributes[i] );
for ( String attribute : value.split( multValuedSeparator ) ) {
attr.add( attribute );
}
attrs.put( attr );
} else {View on GitHub (pinned to f3058517a1)