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

  1. Inspect e.getCause() to tell whether the failure was on the insert or the modify path.
  2. Ensure the parent OU exists before upserting new entries.
  3. Verify bind account has both create and write rights on the target subtree.
  4. Validate attributes/values against the objectClass schema (required and allowed attributes).
  5. 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

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


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)