apache/seatunnel · warning
Failed to load finished job DAG for job
Error message
Failed to load finished job DAG for job {}: {} What it means
getFinishedJobDAGInfo fetches a finished job's DAG (JobDAGInfo) from the finished-job DAG IMap. On any Throwable it logs this warning and returns null, so callers render the finished job without DAG data instead of failing the whole REST response.
Solutions
- Confirm all cluster members are healthy and partitions are not migrating; retry the query.
- If deserialization errors, align SeaTunnel versions across members or purge stale finished-job DAG entries.
- Increase Hazelcast operation call timeout for large DAG values.
- Re-check whether the job's DAG was ever persisted; finished jobs from before persistence existed will simply be missing.
Example fix
// before
// JobDAGInfo dag = finishedJobDAGInfo.get(jobId);
// after (service-internal behavior to mirror in callers)
// try { dag = finishedJobDAGInfo.get(jobId); } catch (Throwable t) { log.warn(...); dag = null; }
// if (dag == null) { render job without DAG } Defensive patterns
Strategy: try-catch
Try / catch
JobDAGInfo dag = null;
try {
dag = getFinishedJobDAGInfo(finishedJobDAGInfo, jobId);
} catch (Throwable t) {
log.warn("DAG unavailable for job {}", jobId, t);
}
if (dag == null) { renderJobWithoutDag(jobId); } Prevention
- Handle null DAG gracefully in REST consumers
- Align cluster versions to prevent JobDAGInfo deserialization failures
- Check node health before querying finished-job data
When it happens
Trigger: Querying finished jobs REST API while the DAG entry is unreadable: Hazelcast member holding the partition is down, operation timeout, deserialization failure of JobDAGInfo, or the DAG map entry was evicted/expired.
Common situations: Cluster membership churn during query; mixed-version cluster where old serialized JobDAGInfo cannot be deserialized; large DAG entries timing out under load; map eviction policy removing old entries.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Failed to load finished job metrics for job
- Failed to get HTTP port from member
- running-jobs summary slow: total=
- A deserialization failure event arrived
- Cannot reliably determine vertex assignment for table
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/d8f8d034a0a6591c.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java:165
private String getFinishedJobMetricsJson(Long jobId) {
try {
IMap<Long, JobMetrics> finishedJobMetrics =
nodeEngine.getHazelcastInstance().getMap(Constant.IMAP_FINISHED_JOB_METRICS);
JobMetrics metrics = finishedJobMetrics.getOrDefault(jobId, JobMetrics.empty());
return metrics == null ? JobMetrics.empty().toJsonString() : metrics.toJsonString();
} catch (Throwable t) {
log.warn("Failed to load finished job metrics for job {}: {}", jobId, t.getMessage());
return JobMetrics.empty().toJsonString();
}
}
private JobDAGInfo getFinishedJobDAGInfo(
IMap<Long, JobDAGInfo> finishedJobDAGInfo, Long jobId) {
try {
return finishedJobDAGInfo.get(jobId);
} catch (Throwable t) {
log.warn("Failed to load finished job DAG for job {}: {}", jobId, t.getMessage());
return null;
}
}
public JsonArray getRunningJobsJson() {
IMap<Long, JobInfo> values = getRunningJobInfoMap();
SeaTunnelServer seaTunnelServer = getSeaTunnelServer(true);
return values.entrySet().stream()
.filter(entry -> shouldShowAsRunningJob(seaTunnelServer, entry.getKey()))
.sorted(
Comparator.comparing(
entry -> entry.getValue().getInitializationTimestamp(),
Comparator.reverseOrder()))
.map(
jobInfoEntry ->
convertToJson(
jobInfoEntry.getValue(), jobInfoEntry.getKey(), false))
.collect(JsonArray::new, JsonArray::add, JsonArray::add);View on GitHub (pinned to cf67b549a7)