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
- Read the 'caused by' exception in the worker log to find the exact AWS error code
- Verify the applicationId exists and is in STARTED state in the configured region
- Check aws.emr.* credentials config or the DefaultAWSCredentialsProviderChain on the worker (env vars, ~/.aws, instance profile)
- Validate executionRoleArn IAM policy (emr-serverless:StartJobRun plus S3 read/write on script and log locations)
- 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
- Validate the JSON request shape locally with the same Jackson ObjectMapper before deploying
- Verify the EMR Serverless application is STARTED and in the client's region before submitting
- Attach an IAM policy granting emr-serverless:StartJobRun plus S3 access to scripts/logs
- Keep aws.emr.* credential config consistent across API/master and worker nodes
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
- Failed to cancel EMR Serverless job run
- EMR Serverless task params are not valid
- jobRunId is empty, cannot track application status
- EMR Serverless task tracking interrupted
- Failed to resolve parameter placeholders
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/9d1427d4710bdc92.
Report an issue: GitHub.