GoogleContainerTools/skaffold · error
timeout waiting for event from pod of kubernetes job: %s
Error message
timeout waiting for event from pod of kubernetes job: %s
What it means
This error fires when the 30-second timer in the pod-event wait select expires before a pod for the k8s job is observed or the context is cancelled. The library waits at most 30 seconds for the job's pod to start emitting events before giving up on attaching logs. It means the job's pod never became visible to the watcher in time.
Source
Thrown at pkg/skaffold/k8sjob/logger/log.go:195
done := make(chan bool)
go func() {
for event := range w.ResultChan() {
pod, ok := event.Object.(*corev1.Pod)
if ok {
podName = pod.Name
done <- true
break
}
}
}()
select {
case <-ctx.Done():
return false, fmt.Errorf("context cancelled for k8s job logging of pod of kubernetes job: %s", "id")
case <-done:
// Continue
case <-time.After(30 * time.Second): // Timeout after 30 seconds
return false, fmt.Errorf("timeout waiting for event from pod of kubernetes job: %s", id)
}
podLogOptions := &corev1.PodLogOptions{
Follow: true,
}
// Stream the logs
req := clientset.CoreV1().Pods(namespace).GetLogs(podName, podLogOptions)
podLogs, err := req.Stream(ctx)
if err != nil {
return false, nil
}
defer podLogs.Close()
io.Copy(tw, podLogs)
l.hadLogsOutput.Store(id, true)
return true, nil
}); waitErr != nil {
// Don't print errors if the user interrupted the logsView on GitHub (pinned to a1189de023)
Solutions
- Increase the 30-second timeout constant in pkg/skaffold/k8sjob/logger/log.go if pulls/scheduling legitimately take longer
- Check the job's pod status with kubectl describe job <job> and kubectl get pods to see why no pod started (ImagePullBackOff, Unschedulable, quota)
- Verify the image reference is valid and pullable from the cluster
- Pre-pull or cache images (e.g. warm nodes or use smaller images) to speed startup
- Check the event watcher filters — ensure the namespace/label selector matches where the pod actually runs
Example fix
// before
case <-time.After(30 * time.Second): // Timeout after 30 seconds
return false, fmt.Errorf("timeout waiting for event from pod of kubernetes job: %s", id)
// after
const podEventTimeout = 2 * time.Minute
case <-time.After(podEventTimeout): Defensive patterns
Strategy: retry
Validate before calling
// Verify the job's pod exists before attaching logs
pods, err := clientset.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{
LabelSelector: "job-name=" + jobName,
})
if err != nil || len(pods.Items) == 0 {
return fmt.Errorf("no pod yet for job %s: %v", jobName, err)
} Try / catch
err := attachLogs(ctx, job)
if err != nil {
if strings.Contains(err.Error(), "timeout waiting for event") {
// inspect pod status and retry once
return retryWithBackoff(2, 5*time.Second, func() error { return attachLogs(ctx, job) })
}
return err
} Prevention
- Size the timeout larger than worst-case image pull + scheduling time
- Pre-pull or pre-load images onto nodes before running the job
- Confirm namespace/label selectors match the job's pod before waiting
- Check cluster capacity (nodes, quotas) before launching long jobs
When it happens
Trigger: The job's pod does not start within 30 seconds of the wait beginning: the job spec fails to create a pod, the image pull is slow, scheduling is pending (unschedulable node, resource quotas), or the pod name/event never matches the watcher's expectations.
Common situations: Large images requiring long pulls, cluster with no available nodes or pending resource quotas, job manifests with long backoff/startup delays, slow or overloaded API server delaying event delivery.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- %q running k8s job timed out after : %v
- STATUSCHECK_CONTAINER_WAITING_UNKNOWN
- %d resources failed to complete their deletion before a new
- c.Message (pod status condition message)
- unable to lookup minikube executable. Please add it to PATH
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/02dbfb951d5e7557.
Report an issue: GitHub.