{"record":{"id":"e4b409c5e9243289","repo":"GoogleContainerTools/skaffold","slug":"context-cancelled-for-k8s-job-logging-of-pod-of-ku","errorCode":null,"errorMessage":"context cancelled for k8s job logging of pod of kubernetes job: %s","messagePattern":"context cancelled for k8s job logging of pod of kubernetes job: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/skaffold/k8sjob/logger/log.go","lineNumber":191,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn false, nil\n\t\t\t}\n\n\t\t\tdone := make(chan bool)\n\t\t\tgo func() {\n\t\t\t\tfor event := range w.ResultChan() {\n\t\t\t\t\tpod, ok := event.Object.(*corev1.Pod)\n\t\t\t\t\tif ok {\n\t\t\t\t\t\tpodName = pod.Name\n\t\t\t\t\t\tdone <- true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn false, fmt.Errorf(\"context cancelled for k8s job logging of pod of kubernetes job: %s\", \"id\")\n\t\t\tcase <-done:\n\t\t\t\t// Continue\n\t\t\tcase <-time.After(30 * time.Second): // Timeout after 30 seconds\n\t\t\t\treturn false, fmt.Errorf(\"timeout waiting for event from pod of kubernetes job: %s\", id)\n\t\t\t}\n\n\t\t\tpodLogOptions := &corev1.PodLogOptions{\n\t\t\t\tFollow: true,\n\t\t\t}\n\n\t\t\t// Stream the logs\n\t\t\treq := clientset.CoreV1().Pods(namespace).GetLogs(podName, podLogOptions)\n\t\t\tpodLogs, err := req.Stream(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\tdefer podLogs.Close()\n\t\t\tio.Copy(tw, podLogs)","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/k8sjob/logger/log.go#L173-L209","documentation":"This error is returned by the k8s job logger's waitForPodAndCheckLoggable-style wait loop when the parent context is cancelled before a pod event for the Kubernetes job is observed. It indicates the log-streaming setup was aborted because the caller (or a shutdown/timeout upstream) cancelled the context, not because the pod failed. It is a normal cancellation signal rather than a Kubernetes failure.","triggerScenarios":"The select in the goroutine-wrapped pod-event wait sees ctx.Done() fire before either the done channel closes or the 30-second timer expires — i.e. the user cancels the skaffold command, Ctrl-C, or an upstream deadline cancels ctx while waiting for the job's pod to appear.","commonSituations":"User aborts a skaffold deploy while k8s job logs are starting; test harnesses cancel contexts to stop log streaming; overall pipeline timeout cancels the context during job startup.","solutions":["No fix needed if cancellation was intentional (e.g. Ctrl-C); treat as expected shutdown","If unexpected, check what cancels ctx upstream (parent deadline, signal handler, pipeline timeout) and extend it","Increase retry tolerance: re-run the deploy so logging re-attaches to the job pod","Handle this error distinctly from the timeout error so cancellations are not logged as failures"],"exampleFix":"// before\ncase <-ctx.Done():\n    return false, fmt.Errorf(\"context cancelled for k8s job logging of pod of kubernetes job: %s\", \"id\")\n// after\ncase <-ctx.Done():\n    return false, ctx.Err() // preserves real cause: context.Canceled vs context.DeadlineExceeded","handlingStrategy":"try-catch","validationCode":"// Go has no pre-check; verify ctx is live before starting\nselect {\ncase <-ctx.Done():\n    return fmt.Errorf(\"context already cancelled: %w\", ctx.Err())\ndefault:\n}","typeGuard":"// Narrow cancellation vs other errors\nfunc isContextCancelled(err error) bool {\n    return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)\n}","tryCatchPattern":"err := startJobLogging(ctx, job)\nif err != nil {\n    if errors.Is(err, context.Canceled) {\n        log.Println(\"log streaming cancelled by caller; shutting down cleanly\")\n        return nil // expected, not a failure\n    }\n    return err\n}","preventionTips":["Pass a context with an explicit timeout sized for pod startup","Treat context.Canceled as a clean shutdown, not an error, in callers","Log the cancellation cause upstream so silent cancels are traceable"],"tags":["kubernetes","context-cancelled","logging"],"backgroundTag":"context-cancelled","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}