apache/dolphinscheduler · error · EmrServerlessTaskException

Failed to get job run status

Error message

Failed to get job run status

What it means

getJobRunState polls GetJobRun for the current job run state. If the response or its jobRun object is null, the plugin cannot determine the state and throws EmrServerlessTaskException with this message; the caller trackApplicationStatus catches it and marks the task EXIT_CODE_FAILURE.

Source

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

        }

        // Set client token for idempotency
        request.setClientToken(taskExecutionContext.getTaskInstanceId() + "-" + System.currentTimeMillis());

        return request;
    }

    /**
     * Get the current state of the job run.
     */
    private String getJobRunState() {
        GetJobRunRequest request = new GetJobRunRequest()
                .withApplicationId(emrServerlessParameters.getApplicationId())
                .withJobRunId(jobRunId);
        GetJobRunResult result = emrServerlessClient.getJobRun(request);

        if (result == null || result.getJobRun() == null) {
            throw new EmrServerlessTaskException("Failed to get job run status");
        }

        JobRun jobRun = result.getJobRun();
        String state = jobRun.getState();
        log.info("EMR Serverless job run [applicationId:{}, jobRunId:{}] state: {}",
                emrServerlessParameters.getApplicationId(), jobRunId, state);
        return state;
    }

    /**
     * Map EMR Serverless job run final state to DolphinScheduler exit code.
     */
    private int mapStateToExitCode(String state) {
        if (state == null) {
            return TaskConstants.EXIT_CODE_FAILURE;
        }
        if (JobRunState.SUCCESS.toString().equals(state)) {
            return TaskConstants.EXIT_CODE_SUCCESS;

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Verify applicationId and jobRunId pair is correct (recovered appIds may be stale or from a different application)
  2. Check AWS console: does the job run still exist for this application?
  3. If using a custom endpoint (emr.serverless.endpoint / EMR_SERVERLESS_ENDPOINT), confirm the mock supports GetJobRun returning a JobRun body
  4. Retry the task; if persistent, inspect worker networking/region settings

Example fix

// before (recovered id may be wrong)
jobRunId = getAppIds();
// after
jobRunId = getAppIds();
if (StringUtils.length(jobRunId) != 0 && !jobRunId.matches("[0-9a-f]{8}.*")) {
    throw new EmrServerlessTaskException("appIds does not look like a jobRunId: " + jobRunId);
}
Defensive patterns

Strategy: retry

Validate before calling

// confirm the job run exists before polling
String recovered = getAppIds();
if (StringUtils.isNotBlank(recovered)) {
    try {
        emrServerlessClient.getJobRun(new GetJobRunRequest()
            .withApplicationId(appId).withJobRunId(recovered)).getJobRun().getState();
    } catch (Exception e) {
        log.warn("Recovered jobRunId {} not resolvable: {}", recovered, e.getMessage());
    }
}

Type guard

boolean isValidJobRunResult(GetJobRunResult r) {
    return r != null && r.getJobRun() != null && StringUtils.isNotEmpty(r.getJobRun().getState());
}

Try / catch

int attempts = 0;
while (attempts++ < 3) {
    try {
        String state = getJobRun(jobRunId);
        break;
    } catch (EmrServerlessTaskException e) {
        if (attempts == 3) { setExitStatusCode(EXIT_CODE_FAILURE); break; }
        TimeUnit.SECONDS.sleep(5);
    }
}

Prevention

When it happens

Trigger: emrServerlessClient.getJobRun(request) returns a result without a JobRun body — AWS returned an empty/unexpected response (e.g. jobRunId no longer resolvable against applicationId, race during cancellation, or a mocked/proxied endpoint like LocalStack returning empty bodies).

Common situations: Testing against LocalStack or a mock endpoint with partial GetJobRun support; jobRunId recovered from appIds refers to a job run deleted or belonging to a different application; transient AWS response anomaly.

Understand the failure class

Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/8cbdc0bc9bb03bae. Report an issue: GitHub.