apache/flink · error · CompletionException

{asynchronousOperationInfo.getFailureCause()}

Error message

{asynchronousOperationInfo.getFailureCause()}

What it means

Thrown when a savepoint disposal operation completes but the JobManager reports a non-null failure cause in the AsynchronousOperationInfo response. After triggering savepoint disposal via REST and polling its status, if the disposal failed (e.g., savepoint path not found, cleanup error), the failure cause is rethrown as a CompletionException.

Source

Thrown at flink-clients/src/main/java/org/apache/flink/client/program/rest/RestClusterClient.java:807

                                    savepointDisposalStatusMessageParameters =
                                            savepointDisposalStatusHeaders
                                                    .getUnresolvedMessageParameters();
                            savepointDisposalStatusMessageParameters.triggerIdPathParameter.resolve(
                                    triggerId);

                            return pollResourceAsync(
                                    () ->
                                            sendRequest(
                                                    savepointDisposalStatusHeaders,
                                                    savepointDisposalStatusMessageParameters));
                        });

        return savepointDisposalFuture.thenApply(
                (AsynchronousOperationInfo asynchronousOperationInfo) -> {
                    if (asynchronousOperationInfo.getFailureCause() == null) {
                        return Acknowledge.get();
                    } else {
                        throw new CompletionException(asynchronousOperationInfo.getFailureCause());
                    }
                });
    }

    @Override
    public CompletableFuture<Set<AbstractID>> listCompletedClusterDatasetIds() {
        return sendRequest(ClusterDataSetListHeaders.INSTANCE)
                .thenApply(
                        clusterDataSetListResponseBody ->
                                clusterDataSetListResponseBody.getDataSets().stream()
                                        .filter(ClusterDataSetEntry::isComplete)
                                        .map(ClusterDataSetEntry::getDataSetId)
                                        .map(id -> new AbstractID(StringUtils.hexStringToByte(id)))
                                        .collect(Collectors.toSet()));
    }

    @Override
    public CompletableFuture<Void> invalidateClusterDataset(AbstractID clusterDatasetId) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Read asynchronousOperationInfo.getFailureCause() for the exact disposal error.
  2. Verify the savepoint path still exists and is accessible from the JobManager.
  3. If already disposed, the error can be safely ignored for idempotent cleanup.
  4. Ensure the filesystem plugin (S3, HDFS) is configured on the JobManager.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    client.disposeSavepoint(savepointPath).get();
} catch (ExecutionException e) {
    Throwable cause = ExceptionUtils.stripExecutionException(e);
    // disposal failure — if already deleted, safe to ignore
    if (!cause.getMessage().contains("not found")) {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling disposeSavepoint(savepointPath) when the savepoint at the given path no longer exists, has already been disposed, or the filesystem backing the savepoint is inaccessible.

Common situations: Savepoint was already manually deleted; savepoint path points to a different cluster's storage; filesystem plugin for the savepoint scheme is missing on the JobManager; permissions error on the savepoint directory.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/83d9e042d06f26dd. Report an issue: GitHub.