What happened?
Summary
SparkClient.wait_for_job_status() can fail too early when a SparkApplication is being retried by Spark Operator.
The SDK currently maps several non-terminal Spark Operator states to SparkJobStatus.FAILED. As a result, callers may receive a failure before the operator has completed its configured retry flow.
Current behavior
SparkJobStatus.from_operator_state() maps these operator states to FAILED:
SUBMISSION_FAILED
FAILING
PENDING_RERUN
INVALIDATING
UNKNOWN
wait_for_job_status() raises as soon as it sees SparkJobStatus.FAILED.
For example, with a retry-enabled RestartPolicy, a job may validly transition through:
SUBMISSION_FAILED
→ PENDING_RERUN
→ SUBMITTED
→ RUNNING
→ COMPLETED
Today, the SDK can raise during SUBMISSION_FAILED or PENDING_RERUN, preventing the caller from waiting for the retry to complete.
Proposed solution
- Add SDK status values for non-terminal states, such as
RETRYING, SUSPENDED, and UNKNOWN.
- Map retry/transition states such as
PENDING_RERUN, INVALIDATING, and retryable submission failures to a non-terminal SDK status.
- Preserve the raw Spark Operator state and
errorMessage on SparkJob so callers can diagnose the current lifecycle state.
- Update
wait_for_job_status() to raise only for a terminal operator FAILED state.
- Treat previously unknown operator states as
UNKNOWN rather than immediately converting them to FAILED.
Acceptance criteria
References
What did you expect to happen?
SparkClient should distinguish terminal failures from retry and transition states.
Spark Operator documents COMPLETED and FAILED as terminal states. Other states may still transition or be retried depending on the configured restart policy.
wait_for_job_status() should continue polling while a job is retrying or transitioning, and raise only when the operator reaches a true terminal failure.
Environment
Kubernetes version:
$ kubectl version
Client Version: v1.31.0
Kubeflow Trainer version:
$ kubectl get pods -n kubeflow -l app.kubernetes.io/name=trainer -o jsonpath="{.items[*].spec.containers[*].image}"
Kubeflow Python SDK version:
Impacted by this bug?
Give it a 👍 We prioritize the issues with most 👍
What happened?
Summary
SparkClient.wait_for_job_status()can fail too early when aSparkApplicationis being retried by Spark Operator.The SDK currently maps several non-terminal Spark Operator states to
SparkJobStatus.FAILED. As a result, callers may receive a failure before the operator has completed its configured retry flow.Current behavior
SparkJobStatus.from_operator_state()maps these operator states toFAILED:SUBMISSION_FAILEDFAILINGPENDING_RERUNINVALIDATINGUNKNOWNwait_for_job_status()raises as soon as it seesSparkJobStatus.FAILED.For example, with a retry-enabled
RestartPolicy, a job may validly transition through:Today, the SDK can raise during
SUBMISSION_FAILEDorPENDING_RERUN, preventing the caller from waiting for the retry to complete.Proposed solution
RETRYING,SUSPENDED, andUNKNOWN.PENDING_RERUN,INVALIDATING, and retryable submission failures to a non-terminal SDK status.errorMessageonSparkJobso callers can diagnose the current lifecycle state.wait_for_job_status()to raise only for a terminal operatorFAILEDstate.UNKNOWNrather than immediately converting them toFAILED.Acceptance criteria
ApplicationStateTypehas a mapping test.PENDING_RERUNtoRUNNINGand thenCOMPLETEDdoes not raise fromwait_for_job_status().FAILEDjob still raises whenFAILEDis not one of the requested target states.SparkJobexposes the raw operator state and error message when available.References
ApplicationStateType: https://github.com/kubeflow/spark-operator/blob/master/api/v1beta2/sparkapplication_types.goWhat did you expect to happen?
SparkClient should distinguish terminal failures from retry and transition states.
Spark Operator documents
COMPLETEDandFAILEDas terminal states. Other states may still transition or be retried depending on the configured restart policy.wait_for_job_status()should continue polling while a job is retrying or transitioning, and raise only when the operator reaches a true terminal failure.Environment
Kubernetes version:
Kubeflow Trainer version:
$ kubectl get pods -n kubeflow -l app.kubernetes.io/name=trainer -o jsonpath="{.items[*].spec.containers[*].image}"Kubeflow Python SDK version:
Impacted by this bug?
Give it a 👍 We prioritize the issues with most 👍