apache/flink · warning · JobStateUnknownException
Job 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.
Solutions
- Check the JobManager logs for why the job entered SUSPENDED state (restart strategy exhausted, resource unavailable).
- If HA was not enabled, configure high-availability mode so the job can recover from JM failover.
- Increase the restart strategy limits (restart-strategy.fixed-delay.attempts) if the job failed due to transient errors.
- 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
- Enable HA mode so jobs survive JobManager failover.
- Configure an adequate restart strategy.
- Take periodic savepoints for recovery.
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
- {asynchronousOperationInfo.getFailureCause()}
- Blob already exists during attempted commit
- can not recover from the pendingFileRecoverable
- Cannot clean commit: File has trailing junk data.
- Cannot clean commit: Staging file does not exist.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/c37a7c3373a3fe36.
Report an issue: GitHub.
Appendix: 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)