apache/flink · warning · JobStateUnknownException

Job %s is in state SUSPENDED

Error message

Job %s is in state SUSPENDED

What it means

Thrown as a JobStateUnknownException when requestJobStatus polls the REST /jobs/:jobid/status endpoint and the job is in JobStatus.SUSPENDED. A SUSPENDED job is one that was running but has been removed from the scheduler due to a failure (e.g., JobManager restart without recovery, or manual suspension). The client treats SUSPENDED as an unknown terminal state because the job is neither running nor cleanly finished.

Source

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

            return "Unknown address.";
        }
    }

    // -------------------------------------------------------------------------
    // RestClient Helper
    // -------------------------------------------------------------------------

    private CompletableFuture<JobStatus> requestJobStatus(JobID jobId) {
        final JobStatusInfoHeaders jobStatusInfoHeaders = JobStatusInfoHeaders.getInstance();
        final JobMessageParameters params = new JobMessageParameters();
        params.jobPathParameter.resolve(jobId);

        return sendRequest(jobStatusInfoHeaders, params)
                .thenApply(JobStatusInfo::getJobStatus)
                .thenApply(
                        jobStatus -> {
                            if (jobStatus == JobStatus.SUSPENDED) {
                                throw new JobStateUnknownException(
                                        String.format("Job %s is in state SUSPENDED", jobId));
                            }
                            return jobStatus;
                        });
    }

    private static class JobStateUnknownException extends RuntimeException {
        public JobStateUnknownException(String message) {
            super(message);
        }
    }

    private CompletableFuture<JobResult> requestJobResultInternal(@Nonnull JobID jobId) {
        return pollResourceAsync(
                        () -> {
                            final JobMessageParameters messageParameters =
                                    new JobMessageParameters();
                            messageParameters.jobPathParameter.resolve(jobId);

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Check the JobManager logs for why the job entered SUSPENDED state (restart strategy exhausted, resource unavailable).
  2. If HA was not enabled, configure high-availability mode so the job can recover from JM failover.
  3. Increase the restart strategy limits (restart-strategy.fixed-delay.attempts) if the job failed due to transient errors.
  4. Restart the job from the latest savepoint or checkpoint.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    JobStatus status = client.getJobStatus(jobId).get();
} catch (ExecutionException e) {
    Throwable cause = ExceptionUtils.stripExecutionException(e);
    if (cause instanceof RestClusterClient.JobStateUnknownException) {
        // job is SUSPENDED — may need to restart from savepoint
        log.warn("Job {} is suspended, attempting recovery from savepoint", jobId);
    }
}

Prevention

When it happens

Trigger: Polling job status via getJobStatus(jobId) when the job has been suspended — typically after a JobManager failover where the job could not be recovered, or when a job is manually suspended via the REST API.

Common situations: JobManager restarted from a checkpoint/savepoint but the job was not configured for HA recovery; job exceeded the restart strategy limit and was suspended; manual suspension via REST PATCH /jobs/:jobid; concurrent job cancellation from another client.

Related errors


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