GoogleContainerTools/skaffold · error
failed to execute container %s hook %d for artifact %q: %w
Error message
failed to execute container %s hook %d for artifact %q: %w
What it means
Skaffold also supports container hooks — commands executed inside the running artifact's container during sync. If such a hook's run() returns any error (Skip handling doesn't apply here), run wraps it with the phase, 1-based hook index, artifact image name, and underlying cause, aborting the sync.
Source
Thrown at pkg/skaffold/hooks/sync.go:97
output.Default.Fprintf(out, "Starting %s hooks for artifact %q...\n", phase, r.imageName)
}
env := r.getEnv()
for i, h := range hooks {
if h.HostHook != nil {
hook := hostHook{*h.HostHook, env}
if err := hook.run(ctx, nil, out); err != nil && !errors.Is(err, &Skip{}) {
return fmt.Errorf("failed to execute host %s hook %d for artifact %q: %w", phase, i+1, r.imageName, err)
}
} else if h.ContainerHook != nil {
hook := containerHook{
cfg: *h.ContainerHook,
cli: r.cli,
selector: runningImageSelector(r.imageRef),
namespaces: r.namespaces,
formatter: r.formatter,
}
if err := hook.run(ctx, out); err != nil {
return fmt.Errorf("failed to execute container %s hook %d for artifact %q: %w", phase, i+1, r.imageName, err)
}
}
}
if len(hooks) > 0 {
output.Default.Fprintf(out, "Completed %s hooks for artifact %q\n", phase, r.imageName)
}
return nil
}
View on GitHub (pinned to a1189de023)
Solutions
- Verify the command exists inside the image (docker run <img> <cmd>) and add it to the Dockerfile if missing
- Check the wrapped error: if it's an exec/pod error, ensure the pod is running and the namespaces list matches where the workload runs
- Use sh -c wrapping and correct quoting; for distroless images switch to a host hook or copy a shell in
- Run with --verbosity=debug to see the exact exec command and pod it targeted
Example fix
// before (skaffold.yaml, distroless image)
sync:
hooks:
after:
- container:
command: ["sh", "-c", "touch /tmp/reload"]
// after (use a host hook instead)
sync:
hooks:
after:
- host:
command: ["kubectl", "exec", "deploy/my-app", "--", "kill", "-HUP", "1"] Defensive patterns
Strategy: retry
Validate before calling
// ensure the target pods are running and the command exists in the image: kubectl get pods -n <ns> -l <selector> --field-selector=status.phase=Running docker run --rm <image> <hook_cmd> --help # proves the binary is in the image
Try / catch
if err := syncRunner.RunPostHooks(ctx, out); err != nil {
if strings.Contains(err.Error(), "failed to execute container") {
// often a transient exec/pod-readiness issue: retry once after a short wait
time.Sleep(2 * time.Second)
return syncRunner.RunPostHooks(ctx, out)
}
return err
} Prevention
- Bake hook commands and shells into the image, or use host hooks for distroless images
- Wait for pod readiness before dev/sync loops; verify namespaces match the deployed workload
- Check RBAC allows exec into pods in target namespaces
When it happens
Trigger: A containerHook command fails inside the running container while RunPreHooks/RunPostHooks process sync hooks for the artifact: command not found in the container image, non-zero exit, kubectl exec/transport error reaching the pod, or the container/pod not running in any of the target namespaces.
Common situations: Command present on host but absent in the slim container image; hook requires a shell not installed (distroless images); pod not yet ready so exec fails; RBAC/namespace mismatch preventing exec.
Related errors
- failed to execute host %s hook %d for artifact %q: %w
- pre-sync hooks failed for artifact %q: %w
- post-sync hooks failed for artifact %q: %w
- 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/6237e0a91d834ff6.
Report an issue: GitHub.