apache/seatunnel · error · SalesforceConnectorException

BULK_JOB_CREATE_FAILED

BULK_JOB_CREATE_FAILED

Error message

HTTP " + status + ": " + responseBody

What it means

Thrown by SalesforceClient.createBulkQueryJob when the POST to the Salesforce Bulk API v2 /jobs/query endpoint returns a non-200 status. It carries the HTTP status and response body, indicating the bulk query job could not be created.

Solutions

  1. Check the HTTP status and body in the message for Salesforce's specific error (e.g. InvalidBatchRequest, MALFORMED_QUERY)
  2. Validate the SOQL manually in the Salesforce Developer Console / Workbench
  3. Re-authenticate to obtain a fresh access token
  4. Ensure Bulk API v2 is available/enabled in the org and the integration user has Bulk API permission

Example fix

// before
soql = "SELECT Id, WrongField__c FROM Account"
// after
soql = "SELECT Id, Name FROM Account"  // fields verified in Developer Console
Defensive patterns

Strategy: try-catch

Validate before calling

// validate SOQL first
// SELECT Id FROM Account LIMIT 1 -- run in Developer Console / Workbench

Try / catch

try {
    String jobId = client.createBulkQueryJob(soql, object);
} catch (SalesforceConnectorException e) {
    log.error("Bulk job creation failed: {}", e.getMessage());
    throw e; // surface Salesforce body to the operator
}

Prevention

When it happens

Trigger: Creating a bulk query job with an invalid SOQL string, an invalid/expired access token, or malformed job request JSON (wrong contentType/object fields) so Salesforce returns 400/401/etc.

Common situations: SOQL with unsupported syntax or a nonexistent field in the query used by a tables_configs entry; token refresh failure; Salesforce Bulk API v2 not enabled for the org.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

        HttpPost post = new HttpPost(url);
        post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken);
        post.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
        post.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType());

        try {
            ObjectNode body = objectMapper.createObjectNode();
            body.put("operation", "query");
            body.put("query", soql);
            post.setEntity(
                    new StringEntity(
                            objectMapper.writeValueAsString(body), ContentType.APPLICATION_JSON));

            try (CloseableHttpResponse response = httpClient.execute(post)) {
                int status = response.getStatusLine().getStatusCode();
                String responseBody =
                        EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                if (status != 200) {
                    throw new SalesforceConnectorException(
                            SalesforceConnectorErrorCode.BULK_JOB_CREATE_FAILED,
                            "HTTP " + status + ": " + responseBody);
                }
                String jobId = objectMapper.readTree(responseBody).get("id").asText();
                log.info("Created Bulk API query job {} for SOQL: {}", jobId, soql);
                return jobId;
            }
        } catch (SalesforceConnectorException e) {
            throw e;
        } catch (Exception e) {
            throw new SalesforceConnectorException(
                    SalesforceConnectorErrorCode.BULK_JOB_CREATE_FAILED, e);
        }
    }

    private void waitForJobCompletion(String jobId) {
        String url = authorizedInstanceUrl + String.format(JOB_PATH, params.getApiVersion(), jobId);
        long deadline = System.currentTimeMillis() + params.getJobCompletionTimeoutMs();

View on GitHub (pinned to cf67b549a7)