[RayJob] Don't fail a running Ray job when its submitter dies - #5100
Open
1fanwang wants to merge 2 commits into
Open
[RayJob] Don't fail a running Ray job when its submitter dies#51001fanwang wants to merge 2 commits into
1fanwang wants to merge 2 commits into
Conversation
1fanwang
requested review from
MortalHappiness,
andrewsykim,
kevin85421 and
rueian
as code owners
August 7, 2026 01:35
1fanwang
marked this pull request as draft
August 7, 2026 03:21
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
from
August 7, 2026 04:46
b7de466 to
a849ed7
Compare
1fanwang
marked this pull request as ready for review
August 7, 2026 05:38
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
from
August 7, 2026 05:58
a849ed7 to
d99b67d
Compare
1fanwang
marked this pull request as draft
August 7, 2026 06:39
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
from
August 7, 2026 07:25
d99b67d to
7d15aae
Compare
1fanwang
marked this pull request as ready for review
August 7, 2026 07:26
1fanwang
marked this pull request as draft
August 7, 2026 07:45
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
2 times, most recently
from
August 7, 2026 09:51
3b0b097 to
6f300a7
Compare
The submitter's exit is treated as evidence that the Ray job should be terminal, but it isn't. `ray job logs --follow` returns 0 whenever the log WebSocket closes with a non-abnormal code, so the submitter can finish under a perfectly healthy job — after printing that the job is still RUNNING. When that happens KubeRay waits 30s, overwrites the accurate RUNNING with a fabricated FAILED, and with shutdownAfterJobFinishes deletes the cluster out from under the driver. The grace period was added for the opposite problem: after a head restart the dashboard reports a status that never resolves, so the RayJob would hang. Both cases reach this code with JobStatus RUNNING, which is why the timeout cannot simply be removed. Ask the cluster instead of guessing. A job status is only current while the node running its driver is alive, so check that node against the dashboard's node list before giving up. Ray already reports driver_node_id on the job; this deserializes it and adds an IsNodeAlive call for the check. The check runs after the job-info poll, where both are available. This compares no timestamps and reads no Pod lifecycle, so it is unaffected by readiness probes flapping, by a sidecar submitter dying, and by whether the head restarted before or after the submitter exited. Addresses ray-project#4921. Related: ray-project#2314. Signed-off-by: 1fanwang <1fannnw@gmail.com>
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
from
August 7, 2026 10:12
6f300a7 to
567335e
Compare
1fanwang
marked this pull request as ready for review
August 7, 2026 11:15
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 567335e. Configure here.
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
5 times, most recently
from
August 8, 2026 01:55
0ee0a45 to
9a4bed0
Compare
A submitter killed by the infrastructure — OOMKill, eviction, preemption — exhausts its backoff and fails the submitter Job. KubeRay reads that as the RayJob failing, but the driver runs on the cluster and is unaffected: the job carries on and often succeeds, while the CR reports SubmissionFailed forever. That also leaves jobStatus contradicting jobDeploymentStatus, which is ray-project#2314. ray-project#2317 asked for this and its own repro is "delete the submitter pod while a job is running". The submission-ID half was fixed by ray-project#2579, but that repro still discards a healthy job today. When the job has been observed RUNNING, the submission plainly succeeded, so reporting SubmissionFailed is wrong twice over: it discards a job that is still going and blames a submission that worked. Leave those to the submitter-finished timeout, which already runs after the job-info poll and decides on live cluster state. A failed submitter Job is terminal, so that path always has a reference point, and it needs no extra API calls here. A submission that never produced a running job still fails immediately, and keeps its SubmissionFailed or AppFailed reason. Closes ray-project#2314 Signed-off-by: 1fanwang <1fannnw@gmail.com>
1fanwang
force-pushed
the
fix/submitter-job-failure-consult-job-status
branch
from
August 8, 2026 17:47
9a4bed0 to
7fa69d5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Why are these changes needed?
A submitter killed by the infrastructure — OOMKill, eviction, preemption — exhausts its backoff and fails the submitter Job, and KubeRay reads that as the RayJob failing. The driver runs on the head and is unaffected: the job carries on, often succeeds, and the CR reports
SubmissionFailedforever. That is the contradictory status pair in #2314, open since 2024.#2317 asked for this; its repro script is "delete the submitter pod while a job is running". The submission-ID half was fixed by #2579, but that script still discards a healthy job on
master.Once the job has been observed
RUNNINGthe submission plainly succeeded, soSubmissionFailedis wrong twice over: it discards a live job and blames a submission that worked. Those are left to #5099's submitter-finished timeout, which decides on live cluster state:A failed submitter Job is terminal, so
getJobFinishedConditionsetsfinishedAtand that path always has a reference point. No extra API calls here — it is a field read.A submission that never produced a running job still fails immediately and keeps its
SubmissionFailedorAppFailedreason. Both SidecarMode submitter-failure paths get the same treatment.Related issue number
Closes #2314. Finishes the second half of #2317.
Labels
doc-updates-requiredbreaking-changeChecks
Manual test instructions
kind, operator built from this branch,
rayproject/ray:2.55.1, a 240s entrypoint ending in a marker. Run #2317's script: delete the submitter pod mid-job.Before, on
master— the submitter Job fails, and the CR contradicts GCS permanently:After — same manifest, same kill, submitter Job still
Failed=True:Realistic config, side by side. Head + 2 workers, a driver fanning real Ray tasks to both workers and checkpointing each step,
shutdownAfterJobFinishes: true,ttlSecondsAfterFinished: 0,backoffLimit: 0. Same trigger: kill the head's dashboardJobHeadmodule mid-job.On
master, the cluster is deleted eight seconds later, a third of the way in:On this branch, same manifest, same trigger at step 11/40:
Triage note: with the default
backoffLimit: 2a non-zero exit is retried and the retry reattaches to the running job, which masked this twice. The damage needs an attempt with no retry left (#2314).SidecarMode, same two runs. The guard applies there too:
A genuinely dead job is still failed. The guard keys on
RUNNING, so the worry is a stranded job whose cluster is gone. Force-deleting the head mid-job, guard active and CR readingRUNNING, still goes terminal in seconds:Killing the head's
DashboardAgentis likewise still terminal: the node goesDEAD, and #5099's driver-liveness check lets the submitter-finished timeout fire as before.Unit tests