pentaho/pentaho-kettle · error · KettleException

LDAPConnection.Error.Search

LDAPConnection.Error.Search

Error message

LDAPConnection.Error.Search

What it means

LDAPConnection.search() wraps any exception from the JNDI InitialContext.search() call (LDAP search against the configured search base with the configured filter) in a KettleException with message key 'LDAPConnection.Error.Search'. The root cause is preserved as the cause, so the underlying LDAP error code (e.g. invalid DN, invalid filter, connection failure, size/time limit) is in e.getCause().

Solutions

  1. Inspect e.getCause() to get the real javax.naming exception (CommunicationException, NameNotFoundException, InvalidSearchFilterException, AuthenticationException) and fix accordingly.
  2. Validate the search base DN with ldapsearch, e.g. ldapsearch -H ldap://host -D user -w pass -b 'dc=example,dc=com' '(objectClass=*)'.
  3. Check the filter for balanced parentheses and a valid 'name=value' form.
  4. Verify host, port, username, password and SSL settings in the step/connection config.
  5. Test network reachability: telnet/nc to the LDAP port (389/636).

Example fix

// before
connection.setFilter("(objectClass");
// after
connection.setFilter("(objectClass=person)");
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate before searching
if (searchBase == null || searchBase.trim().isEmpty()) throw new KettleException("Search base is empty");
if (filter == null || !balancedParentheses(filter)) throw new KettleException("Invalid LDAP filter: " + filter);
// then smoke-test with: ldapsearch -H ldap://host -D user -w pass -b "$searchBase" "$filter"

Try / catch

try {
  connection.search();
} catch (KettleException e) {
  Throwable root = ExceptionUtils.getRootCause(e);
  if (root instanceof CommunicationException) { /* fix host/port/SSL */ }
  else if (root instanceof InvalidSearchFilterException) { /* fix filter */ }
  else if (root instanceof NameNotFoundException) { /* fix search base DN */ }
  else if (root instanceof AuthenticationException) { /* fix credentials */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling search() (directly or via getFields during transformation initialization) when: the search base DN does not exist or is malformed; the filter string is not a valid LDAP filter; the LDAP server is unreachable or credentials fail; search controls (scope, size limit, time limit) are invalid.

Common situations: Typo or trailing spaces in the Search Base DN (e.g. 'dc=example,dc=com' written as 'dc=example, dc=com' is fine but 'dc=example' is not); unbalanced parentheses in the filter like '(objectClass' instead of '(objectClass=*)'; searching with an attribute that doesn't exist combined with an invalid filter; firewall/SSL misconfiguration preventing connection; anonymous bind rejected by the directory.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/3dee854a0406e419. Report an issue: GitHub.

Appendix: source

Thrown at plugins/ldap/impl/src/main/java/org/pentaho/di/trans/steps/ldapinput/LDAPConnection.java:270

        }
      }

      if ( nrCtl > 0 ) {
        Control[] ctls = new Control[nrCtl];
        int index = 0;
        if ( ctlk != null ) {
          ctls[index++] = ctlk;
        }
        if ( ctlp != null ) {
          ctls[index++] = ctlp;
        }
        getInitialContext().setRequestControls( ctls );
      }
      // Search for objects using the filter
      this.results = getInitialContext().search( getSearchBase(), getFilter(), getSearchControls() );

    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( "LDAPConnection.Error.Search" ), e );
    }
  }

  public int delete( String dn, boolean checkEntry ) throws KettleException {
    try {

      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

View on GitHub (pinned to f3058517a1)