Skip to content

Fix: native K8s sidecar exit-143 causes false task failure (REMOTE-2365) - #117

Closed
warp-agent-staging[bot] wants to merge 1 commit into
mainfrom
oz-agent/REMOTE-2365
Closed

Fix: native K8s sidecar exit-143 causes false task failure (REMOTE-2365)#117
warp-agent-staging[bot] wants to merge 1 commit into
mainfrom
oz-agent/REMOTE-2365

Conversation

@warp-agent-staging

Copy link
Copy Markdown
Contributor

Problem

When Kubernetes native sidecars (JVM-based services like ZooKeeper, Kafka, Elasticsearch) are declared as initContainers with restartPolicy: Always, the worker falsely reports task failure on shutdown. The kubelet SIGTERMs these sidecars after the main task container completes, and JVM processes always exit with code 143 (128 + SIGTERM). The worker logged an error even though the Kubernetes Job itself reached Complete and the UI showed green Done.

Root Cause

Two bugs in kubernetes.go:

Bug 1 — inspectPodFailure: Treated every init container with a non-zero exit code as a task failure without checking restartPolicy. Kubernetes itself excludes native sidecars (restartPolicy: Always) from pod/Job success determination, but the worker did not.

Bug 2 — Race condition: The pod status update carrying the sidecar exit-143 arrived via the pod watch before the Job controller stamped JobComplete. Since inspectPodFailure saw exit-143 first, the failure path won every time.

Fix

Fix 1 (inspectPodFailure): Build a name → restartPolicy map from pod.Spec.InitContainers. Skip init containers with restartPolicy: Always when evaluating non-zero exit codes. Adds buildInitRestartPolicyMap helper.

Fix 2 (race guard): When inspectPodFailure returns a non-nil failure from the pod watch handler, do a synchronous Job GET before reporting the error. If the Job is already marked Complete, return success — the Job state takes precedence over transient pod events that arrive before the Job controller stamps JobComplete.

Tests Added

  • TestBuildInitRestartPolicyMap: unit test for the new helper
  • TestInspectPodFailureIgnoresNativeSidecarExit143: ZooKeeper + Kafka exit 143 → no error
  • TestInspectPodFailureReportsRegularInitContainerExit: regular init container exit 1 → still reported as failure
  • TestInspectPodFailureIgnoresMixedNativeSidecarsAndPassedSetup: native sidecar exits 143 alongside passing setup init container → no error
  • TestExecuteTaskSucceedsWhenNativeSidecarExits143BeforeJobComplete: end-to-end race: pod watch fires sidecar exit-143 first, job watch delivers Complete 50ms later → success
  • TestExecuteTaskJobCompleteWinsOverTransientPodFailure: race guard: pod watch fires PodFailed, Job GET returns Complete → success

Related

Fixes REMOTE-2365


Conversation: https://staging.warp.dev/conversation/6c426788-7214-456f-a10c-1d4b8739b8fa
Run: https://oz.staging.warp.dev/runs/019faa1e-d87e-7dc2-9d25-000a0106248d

This PR was generated with Oz.

inspectPodFailure treated every init container non-zero exit code as a
task failure without checking restartPolicy. Kubernetes native sidecars
are init containers with restartPolicy: Always, and Kubernetes itself
excludes their exit codes from pod/Job success determination. JVM-based
services (ZooKeeper, Kafka, Elasticsearch) always exit with code 143
(SIGTERM + 128) on clean shutdown — triggering a false task failure.

Fix 1 (inspectPodFailure): Build a name→restartPolicy map from
pod.Spec.InitContainers and skip init containers with restartPolicy:
Always when evaluating non-zero exit codes. Adds buildInitRestartPolicyMap
helper.

Fix 2 (race guard): When inspectPodFailure returns a non-nil failure
from the pod watch handler, do a synchronous Job GET before reporting
the error. If the Job is already marked Complete, return success — the
Job state takes precedence over transient pod events that arrive before
the Job controller stamps JobComplete.

Tests added:
- TestBuildInitRestartPolicyMap: unit test for the new helper
- TestInspectPodFailureIgnoresNativeSidecarExit143: ZooKeeper + Kafka
  exit 143 → no error
- TestInspectPodFailureReportsRegularInitContainerExit: regular init
  container (no restartPolicy) exit 1 → still reported as failure
- TestInspectPodFailureIgnoresMixedNativeSidecarsAndPassedSetup: native
  sidecar exits 143 alongside a passing setup init container → no error
- TestExecuteTaskSucceedsWhenNativeSidecarExits143BeforeJobComplete:
  end-to-end race simulation: pod watch fires sidecar exit-143 first,
  job watch delivers Complete 50ms later → outcome is success
- TestExecuteTaskJobCompleteWinsOverTransientPodFailure: race guard
  test: pod watch fires PodFailed, Job GET returns Complete → success

Fixes REMOTE-2365

Co-Authored-By: Oz <oz-agent@warp.dev>
@warp-agent-staging warp-agent-staging Bot added the from-feedback-bot Linear issue delegated from Feedback Bot label Jul 28, 2026
@captainsafia

Copy link
Copy Markdown
Contributor

Superseded by #118.

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

Labels

from-feedback-bot Linear issue delegated from Feedback Bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants