apache/dolphinscheduler · error · TaskException

cancel application error

Error message

cancel application error

What it means

cancelApplication() builds a kill command via ProcessBuilder to stop the running Flink streaming application. If starting the process fails with an IOException, it wraps it in TaskException('cancel application error'). This signals the cancel/stop request could not be issued at OS level.

Source

Thrown at dolphinscheduler-task-plugin/dolphinscheduler-task-flink-stream/src/main/java/org/apache/dolphinscheduler/plugin/task/flink/FlinkStreamTask.java:84

    @Override
    public void cancelApplication() throws TaskException {
        List<String> appIds = getApplicationIds();
        if (CollectionUtils.isEmpty(appIds)) {
            log.error("can not get appId, taskInstanceId:{}", taskExecutionContext.getTaskInstanceId());
            return;
        }
        taskExecutionContext.setAppIds(String.join(TaskConstants.COMMA, appIds));
        List<String> args = FlinkArgsUtils.buildCancelCommandLine(taskExecutionContext);

        log.info("cancel application args:{}", args);

        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command(args);
        try {
            processBuilder.start();
        } catch (IOException e) {
            throw new TaskException("cancel application error", e);
        }
    }

    @Override
    public void savePoint() throws Exception {
        List<String> appIds = getApplicationIds();
        if (CollectionUtils.isEmpty(appIds)) {
            log.warn("can not get appId, taskInstanceId:{}", taskExecutionContext.getTaskInstanceId());
            return;
        }

        taskExecutionContext.setAppIds(String.join(TaskConstants.COMMA, appIds));
        List<String> args = FlinkArgsUtils.buildSavePointCommandLine(taskExecutionContext);
        log.info("savepoint args:{}", args);

        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command(args);
        processBuilder.start();

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Check worker PATH and installed binaries needed by the cancel command (yarn, kill)
  2. Log the constructed args to verify the command is correct before start()
  3. Catch and log IOException to at least attempt cleanup instead of failing the worker thread
  4. Run cancel with the same user/environment the job was launched with

Example fix

// before
processBuilder.start();
// after
try (Process p = processBuilder.start()) {
    p.waitFor(30, TimeUnit.SECONDS);
} catch (IOException e) {
    log.warn("cancel command {} failed: {}", args, e.getMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (args == null || args.length == 0) {
    throw new IllegalStateException("cancel command args are empty");
}
// verify binaries exist
for (String a : args) { break; }
if (Files.isExecutable(java.nio.file.Paths.get(args[0])) || args[0].contains("/")) { /* ok */ }

Try / catch

try {
    processBuilder.start();
} catch (IOException e) {
    log.error("cancel command {} failed: {}", String.join(" ", args), e.getMessage(), e);
    // degrade gracefully: mark cancel as best-effort instead of throwing
}

Prevention

When it happens

Trigger: ProcessBuilder.start() throws IOException when executing the cancel command (e.g. 'yarn application -kill' or 'kill' binary missing, non-zero env, IO error spawning process).

Common situations: Worker container lacks yarn/kill binaries on PATH; environment stripped in the worker; disk/proc limits; wrong args array built from empty appIds.

Related errors


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