Skip to content

[RayJob] Fail fast on SidecarMode submitter failure during Initializing#4946

Open
tmrtmrtmrtmr wants to merge 2 commits into
ray-project:masterfrom
tmrtmrtmrtmr:fix/sidecar-initializing-submitter-failfast
Open

[RayJob] Fail fast on SidecarMode submitter failure during Initializing#4946
tmrtmrtmrtmr wants to merge 2 commits into
ray-project:masterfrom
tmrtmrtmrtmr:fix/sidecar-initializing-submitter-failfast

Conversation

@tmrtmrtmrtmr

@tmrtmrtmrtmr tmrtmrtmrtmr commented Jun 23, 2026

Copy link
Copy Markdown

Why are these changes needed?

In SidecarMode, the ray-job-submitter runs as a container inside the head Pod with the head Pod's RestartPolicy set to Never. If the submitter exits non-zero before the RayCluster reaches Ready (e.g. the job fails while workers are still being scheduled), the terminated submitter container keeps the head Pod Ready=False, so RayCluster.Status.State never becomes Ready.

The RayJob Initializing -> Running transition is gated on RayCluster.Status.State == Ready, and the only submitter-failure detector (checkSubmitterAndUpdateStatusIfNeeded) runs only in the Running state. As a result the RayJob is wedged in Initializing forever: it never transitions to Failed, shutdownAfterJobFinishes never runs, and the autoscaler keeps retrying workers — even though the submitter failure is already observable.

This PR detects a terminal submitter failure during Initializing (SidecarMode) and fails fast. The feature-gate-aware detection (SidecarSubmitterRestart) is extracted into checkSidecarSubmitterFailedAndUpdateStatus and shared by the Initializing and Running states; the Initializing call skips when the head Pod does not exist yet.

Related issue number

Closes #4945

Checks

  • I've made sure the tests are passing.

Testing:

  • go build ./controllers/ray/..., go vet ./controllers/ray/, gofumpt -l — clean
  • New unit test TestCheckSidecarSubmitterFailedAndUpdateStatus: submitter Terminated exit != 0 → Failed/SubmissionFailed; same with JobStatus already FailedAppFailed; exit 0 → no-op; still Running → no-op; SidecarSubmitterRestart enabled → routes to the restart-count check
  • go test ./controllers/ray/ -run 'TestCheckSidecarSubmitterFailedAndUpdateStatus|TestCheckIsRestartCountExceeded' — pass

In SidecarMode the `ray-job-submitter` runs as a container inside the head
Pod, with the head Pod's RestartPolicy forced to Never. If that submitter
exits non-zero before the RayCluster reaches the `Ready` state (for example,
the job fails while workers are still being scheduled), the terminated
submitter container keeps the head Pod NotReady, so the RayCluster never
reaches `Ready`.

The RayJob `Initializing -> Running` transition is gated on
`RayCluster.Status.State == Ready`, and the only submitter-failure detector
(`checkSubmitterAndUpdateStatusIfNeeded`) runs exclusively in the `Running`
state. As a result the RayJob is wedged in `Initializing` forever: it never
transitions to `Failed`, `shutdownAfterJobFinishes` never runs, and the
cluster is never torn down while the autoscaler keeps retrying workers.

Detect a terminal submitter failure during the `Initializing` state (for
SidecarMode) and fail fast. The shared, feature-gate-aware detection logic is
extracted into `checkSidecarSubmitterFailedAndUpdateStatus` so the
`Initializing` and `Running` states stay consistent (including the
`SidecarSubmitterRestart` feature gate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Timur Vankov <timur.vankov@silvermont.team>
@tmrtmrtmrtmr
tmrtmrtmrtmr force-pushed the fix/sidecar-initializing-submitter-failfast branch from 514b835 to 9aa0f23 Compare June 23, 2026 19:47
…ng Initializing

The Initializing fail-fast set the failure reason from `rayJob.Status.JobStatus`
(`AppFailed` when the job ran and failed, `SubmissionFailed` otherwise), but the
job status is only polled in the `Running` state, so during `Initializing` it is
always empty and the reason was always `SubmissionFailed`. That is wrong for a
genuine application failure that fails while the cluster is still initializing
(e.g. the e2e "Failing RayJob without cluster shutdown" case, which asserts
`AppFailed`).

When the submitter sidecar has failed during `Initializing`, best-effort poll
the Ray job status from the dashboard before deciding the reason. The dashboard
URL is resolved via the head Service (already up in SidecarMode) when
`Status.DashboardURL` is not yet set. The poll is a no-op on any error (no
dashboard client, empty JobId, URL resolution failure, dashboard unreachable,
job not found), so the reason falls back to `SubmissionFailed` when the job
status cannot be determined.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Timur Vankov <timur.vankov@silvermont.team>
@AndySung320

Copy link
Copy Markdown
Contributor

cc @machichima
I think you're designing the similar stuff.

@machichima

Copy link
Copy Markdown
Collaborator

cc @machichima I think you're designing the similar stuff.

I am drafting the design for #4637, which focus on the case where head pod failed, which is a bit different from this PR

rayJob.Status.JobStatus = jobInfo.JobStatus
}

func (r *RayJobReconciler) checkSidecarSubmitterFailedAndUpdateStatus(ctx context.Context, rayJob *rayv1.RayJob, headPod *corev1.Pod) bool {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some duplicate code between this function and checkSidecarSubmitterFailed. Could we have checkSidecarSubmitterFailed do the detection and return the container status, then pass that status into this function so it only focuses on updating the status? And maybe rename them to something like detectSidecarSubmitterFailure and updateStatusForSidecarSubmitterFailure.

Then we can drop "It uses the same detection logic as checkSidecarSubmitterFailedAndUpdateStatus so the two stay in sync." comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#4981
I finish it
@machichima

@justinyeh1995

Copy link
Copy Markdown
Contributor

Hi @tmrtmrtmrtmr, do you mind addressing the review comment when you get the time?

@tmrtmrtmrtmr

Copy link
Copy Markdown
Author

Hi @tmrtmrtmrtmr, do you mind addressing the review comment when you get the time?

yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] SidecarMode RayJob stuck in Initializing forever when the submitter fails before the RayCluster is Ready

5 participants