apache/dolphinscheduler · error · TaskException

EMR Serverless task submit failed

Error message

EMR Serverless task submit failed

What it means

Dolphinscheduler's EMR Serverless plugin wraps any failure during the StartJobRun call (request-building errors from buildStartJobRunRequest or AWS SDK SdkBaseException) into a TaskException with this message. It means the job run was not accepted by the EMR Serverless service, so no jobRunId exists to track. The original AWS exception is attached as the cause and logged.

Source

Thrown at dolphinscheduler-task-plugin/dolphinscheduler-task-emr-serverless/src/main/java/org/apache/dolphinscheduler/plugin/task/emrserverless/EmrServerlessTask.java:143

    }

    @Override
    public void submitApplication() throws TaskException {
        try {
            StartJobRunRequest request = buildStartJobRunRequest();

            log.info("Submitting EMR Serverless job run to application: {}",
                    emrServerlessParameters.getApplicationId());
            StartJobRunResult result = emrServerlessClient.startJobRun(request);

            jobRunId = result.getJobRunId();
            // Store jobRunId for failover recovery; applicationId is always available from parameters
            setAppIds(jobRunId);
            log.info("Successfully submitted EMR Serverless job run, jobRunId: {}", jobRunId);

        } catch (EmrServerlessTaskException | SdkBaseException e) {
            log.error("EMR Serverless task submit failed", e);
            throw new TaskException("EMR Serverless task submit failed", e);
        }
    }

    @Override
    public void trackApplicationStatus() throws TaskException {
        try {
            // Recover jobRunId from appIds if needed (failover case)
            if (StringUtils.isEmpty(jobRunId) && StringUtils.isNotEmpty(getAppIds())) {
                jobRunId = getAppIds();
                log.info("Recovered EMR Serverless jobRunId from appIds: {}", jobRunId);
            }

            if (StringUtils.isEmpty(jobRunId)) {
                throw new EmrServerlessTaskException("jobRunId is empty, cannot track application status");
            }

            String currentState = getJobRunState();
            while (WAITING_STATES.contains(currentState)) {

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Read the 'caused by' exception in the worker log to find the exact AWS error code
  2. Verify the applicationId exists and is in STARTED state in the configured region
  3. Check aws.emr.* credentials config or the DefaultAWSCredentialsProviderChain on the worker (env vars, ~/.aws, instance profile)
  4. Validate executionRoleArn IAM policy (emr-serverless:StartJobRun plus S3 read/write on script and log locations)
  5. Validate the startJobRunRequestJson against the AWS StartJobRun API shape (UpperCamelCase keys, e.g. jobDriver, releaseLabel)

Example fix

// before
startJobRunRequestJson = "{ \"jobDriver\": { \"sparkSubmit\": { \"entryPoint\": \"s3://bucket/job.py\" } } }" // missing releaseLabel -> ValidationException
// after
startJobRunRequestJson = "{ \"releaseLabel\": \"emr-6.9.0\", \"jobDriver\": { \"sparkSubmitJobDriver\": { \"sparkSubmitParameters\": \"--conf spark.executor.instances=2\", \"entryPoint\": \"s3://bucket/job.py\" } } }"
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight checks before task run
if (StringUtils.isBlank(emrServerlessParameters.getApplicationId())) throw new IllegalArgumentException("applicationId required");
if (StringUtils.isBlank(emrServerlessParameters.getStartJobRunRequestJson())) throw new IllegalArgumentException("startJobRunRequestJson required");
objectMapper.readTree(emrServerlessParameters.getStartJobRunRequestJson()); // fail fast on invalid JSON
// ensure AWS creds resolvable:
new DefaultAWSCredentialsProviderChain().getCredentials();

Type guard

boolean isSdkBaseException(Throwable t) {
    return t instanceof SdkBaseException || t.getCause() instanceof SdkBaseException;
}

Try / catch

try {
    emrServerlessClient.startJobRun(request);
} catch (SdkBaseException e) {
    log.error("AWS error code={} requestId={}", e instanceof AmazonServiceException
        ? ((AmazonServiceException) e).getErrorCode() : "client",
        e instanceof AmazonServiceException ? ((AmazonServiceException) e).getRequestId() : "n/a", e);
    throw new TaskException("EMR Serverless task submit failed", e);
}

Prevention

When it happens

Trigger: emrServerlessClient.startJobRun(request) throws an AWS SDK exception: invalid applicationId (application not found / not started), executionRoleArn missing permissions, malformed startJobRunRequestJson, invalid job driver config (Spark submit args), network/credential failures, or a nested EmrServerlessTaskException from placeholder resolution or JSON parsing in buildStartJobRunRequest.

Common situations: Application ID typo or application in wrong region; IAM role lacking emr-serverless:StartJobRun or S3 access to scripts; bad JSON payload with wrong case keys (UpperCamelCaseStrategy is required); expired AWS credentials in the worker environment; VPC/endpoint misconfiguration blocking the AWS API.

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/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/9d1427d4710bdc92. Report an issue: GitHub.