apache/seatunnel · critical · SalesforceConnectorException

AUTH_FAILED

AUTH_FAILED

Error message

HTTP " + status + ": " + body

What it means

SalesforceClient.authenticate posts the OAuth credentials to Salesforce's token endpoint and requires HTTP 200. Any other status throws SalesforceConnectorException(AUTH_FAILED) with the status code and response body, since the token exchange did not yield an access token.

Source

Thrown at seatunnel-connectors-v2/connector-salesforce/src/main/java/org/apache/seatunnel/connectors/seatunnel/salesforce/client/SalesforceClient.java:110

        String tokenUrl = params.getInstanceUrl() + TOKEN_PATH;
        HttpPost post = new HttpPost(tokenUrl);

        List<NameValuePair> form = new ArrayList<>();
        form.add(new BasicNameValuePair("grant_type", "password"));
        form.add(new BasicNameValuePair("client_id", params.getClientId()));
        form.add(new BasicNameValuePair("client_secret", params.getClientSecret()));
        form.add(new BasicNameValuePair("username", params.getUsername()));
        form.add(
                new BasicNameValuePair(
                        "password", params.getPassword() + params.getSecurityToken()));

        try {
            post.setEntity(new UrlEncodedFormEntity(form, StandardCharsets.UTF_8));
            try (CloseableHttpResponse response = httpClient.execute(post)) {
                int status = response.getStatusLine().getStatusCode();
                String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                if (status != 200) {
                    throw new SalesforceConnectorException(
                            SalesforceConnectorErrorCode.AUTH_FAILED,
                            "HTTP " + status + ": " + body);
                }
                JsonNode json = objectMapper.readTree(body);
                this.accessToken = json.get("access_token").asText();
                this.authorizedInstanceUrl = json.get("instance_url").asText();
                log.info("Authenticated with Salesforce instance {}", authorizedInstanceUrl);
            }
        } catch (SalesforceConnectorException e) {
            throw e;
        } catch (Exception e) {
            throw new SalesforceConnectorException(SalesforceConnectorErrorCode.AUTH_FAILED, e);
        }
    }

    public CatalogTable describeObject(String database, String objectName) {
        String url =
                authorizedInstanceUrl

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read the response body in the error message — Salesforce returns e.g. {"error":"invalid_grant","error_description":"..."} and fix the matching credential
  2. Verify client_id, client_secret, username, password+security_token against the connected app in Salesforce setup
  3. Confirm the auth endpoint URL (login vs test/sandbox: https://login.salesforce.com vs https://test.salesforce.com)
  4. If using refresh tokens, re-run the OAuth flow to obtain a fresh token

Example fix

// before
auth_url = "https://login.salesforce.com/services/oauth2/token" // sandbox user
// after
auth_url = "https://test.salesforce.com/services/oauth2/token"
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight token request before the job
curl -X POST $AUTH_URL -d grant_type=password -d client_id=... -d client_secret=...
// expect HTTP 200 with access_token

Try / catch

try {
    client.authenticate();
} catch (SalesforceConnectorException e) {
    if (e.getSeaTunnelErrorCode() == SalesforceConnectorErrorCode.AUTH_FAILED) {
        // parse e.getMessage() body: refresh credentials or re-run OAuth flow
    } else throw e;
}

Prevention

When it happens

Trigger: The OAuth token POST returns non-200 — invalid client_id/client_secret, wrong username/password, expired or revoked refresh token, locked account, or the authorized endpoint URL is wrong. Raised in authenticate() before any data flows.

Common situations: Rotated Salesforce passwords invalidating security tokens, IP not in Salesforce trusted ranges, sandbox vs production login URL mixups, or expired connected-app credentials.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/e11bad82a8d6707a. Report an issue: GitHub.