pentaho/pentaho-kettle · error · KettleException

SalesforceInput.Exception.CanNotGetBiding

SalesforceInput.Exception.CanNotGetBiding

Error message

SalesforceInput.Exception.CanNotGetBiding

What it means

query() throws this KettleException when getBinding() returns null, meaning the connection has not been established (or was reset) before querying. The SOAP binding stub is the session handle to Salesforce; without it no query can be issued.

Solutions

  1. Call connect() (or getConnection()) before query() and check it succeeds.
  2. Wrap the connect+query sequence so a failed connect aborts instead of proceeding to query.
  3. Add reconnection logic that re-establishes the binding when the session expires.
  4. Log the connection state before querying to catch initialization-order bugs early.

Example fix

// before
SalesforceConnection conn = new SalesforceConnection(log, url, user, pass);
conn.query(false); // binding never created
// after
conn.connect();
conn.query(false);
Defensive patterns

Strategy: validation

Validate before calling

if (conn.getBinding() == null) {
  conn.connect(); // establish session before querying
}

Try / catch

try {
  conn.query(specifyQuery);
} catch (KettleException e) {
  if (e.getMessage().contains("CanNotGetBiding")) {
    conn.connect();
    conn.query(specifyQuery); // one reconnect retry
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling query() without a prior successful connect(); connect() failed earlier but the error was swallowed; the binding was never initialized because getConnection() was skipped.

Common situations: Custom Java code (or a step variant) calling query() directly without connect(); session invalidated by the server long-running job without reconnect logic; typo in initialization order.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at plugins/salesforce/core/src/main/java/org/pentaho/di/trans/steps/salesforce/SalesforceConnection.java:384

      ExceptionCode exCode = ex.getExceptionCode();
      if ( exCode == ExceptionCode.FUNCTIONALITY_NOT_ENABLED
        || exCode == ExceptionCode.INVALID_CLIENT || exCode == ExceptionCode.INVALID_LOGIN
        || exCode == ExceptionCode.LOGIN_DURING_RESTRICTED_DOMAIN
        || exCode == ExceptionCode.LOGIN_DURING_RESTRICTED_TIME || exCode == ExceptionCode.ORG_LOCKED
        || exCode == ExceptionCode.PASSWORD_LOCKOUT || exCode == ExceptionCode.SERVER_UNAVAILABLE
        || exCode == ExceptionCode.TRIAL_EXPIRED || exCode == ExceptionCode.UNSUPPORTED_CLIENT ) {
        throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Error.InvalidUsernameOrPassword" ) );
      }
      throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Error.Connection" ), ex );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Error.Connection" ), e );
    }
  }

  public void query( boolean specifyQuery ) throws KettleException {

    if ( getBinding() == null ) {
      throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.Exception.CanNotGetBiding" ) );
    }

    try {
      if ( !specifyQuery ) {
        // check if we can query this Object
        DescribeSObjectResult describeSObjectResult = getBinding().describeSObject( getModule() );
        if ( describeSObjectResult == null ) {
          throw new KettleException( BaseMessages.getString( PKG, "SalesforceInput.ErrorGettingObject" ) );
        }
        if ( !describeSObjectResult.isQueryable() ) {
          throw new KettleException( BaseMessages.getString(
            PKG, "SalesforceInputDialog.ObjectNotQueryable", module ) );
        }
        if ( this.recordsFilter == SalesforceConnectionUtils.RECORDS_FILTER_UPDATED
          || this.recordsFilter == SalesforceConnectionUtils.RECORDS_FILTER_DELETED ) {
          // The object must be replicateable
          if ( !describeSObjectResult.isReplicateable() ) {
            throw new KettleException( BaseMessages.getString(

View on GitHub (pinned to f3058517a1)