PreStopHookError occurs when a preStop lifecycle hook fails during pod termination. The hook failure is logged but termination continues. Ensure hooks complete within the grace period.
PreStopHookError (FailedPreStopHook) occurs when a container's preStop lifecycle hook fails during pod termination. Unlike postStart hooks, preStop hook failures don't prevent termination—the pod continues shutting down regardless. PreStop hooks run synchronously before SIGTERM is sent to the container. They're used for graceful shutdown tasks like draining connections, deregistering from service discovery, or completing in-flight requests. Failures are logged as warnings but don't block termination.
View events during pod deletion:
kubectl describe pod <pod-name>
kubectl get events --field-selector involvedObject.name=<pod-name>Look for:
- FailedPreStopHook warnings
- Killing container with grace period messages
- Time between termination start and completion
The preStop hook must finish within terminationGracePeriodSeconds:
spec:
terminationGracePeriodSeconds: 60 # Total time for hook + shutdown
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/scripts/graceful-shutdown.sh"] # Must complete in < 60sIf your hook takes 30 seconds and container needs 10 seconds to stop, set grace period to at least 45 seconds.
Test the hook in a running container:
kubectl exec -it <pod-name> -- /bin/sh
# Run the hook command
/scripts/graceful-shutdown.sh
echo $? # Should be 0
time /scripts/graceful-shutdown.sh # Check durationEnsure the script exists, is executable, and completes quickly.
Common configuration mistakes:
# Wrong - extra quotes
command: ['"/bin/sh"', '-c', 'sleep 10']
# Correct
command: ["/bin/sh", "-c", "sleep 10"]
# Wrong - missing array brackets
command: /bin/sh -c "sleep 10"
# Correct
command: ["/bin/sh", "-c", "sleep 10"]Validate YAML syntax before applying.
PreStop output isn't captured by kubectl logs. Redirect to PID 1:
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- |
echo "Starting graceful shutdown" > /proc/1/fd/1
/scripts/shutdown.sh > /proc/1/fd/1 2>&1
echo "Shutdown complete" > /proc/1/fd/1This helps debug what the hook is doing during termination.
If preStop is problematic, consider these alternatives:
Handle SIGTERM in application:
import signal
def shutdown(signum, frame):
drain_connections()
sys.exit(0)
signal.signal(signal.SIGTERM, shutdown)Use a sidecar for cleanup:
Sidecars can handle deregistration independently.
Increase grace period:
Give more time if shutdown genuinely needs it.
PreStop hook execution timeline:
1. Pod deletion requested
2. Pod removed from Service endpoints
3. PreStop hook executes (synchronous)
4. SIGTERM sent to container
5. Container has remaining grace period to exit
6. SIGKILL sent if still running
Kubernetes adds 2 extra seconds if the grace period is exceeded but hook is still running. After that, forceful termination occurs.
PreStop hooks don't run if:
- Container is already terminated
- Pod is in Failed or Succeeded phase
- Node is forcefully terminated
For zero-downtime deployments, combine preStop with readiness probe failures:
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"] # Wait for endpoints to updateThis gives load balancers time to stop sending traffic before the container stops.
Service port already allocated
How to fix "Service port already allocated" in Kubernetes
minimum cpu usage per Container
How to fix "minimum cpu usage per Container" in Kubernetes
Failed to connect to server: connection refused (HTTP/2)
How to fix "HTTP/2 connection refused" error in Kubernetes
No subnets found for EKS cluster
How to fix "eks subnet not found" in Kubernetes
missing request for cpu in container
How to fix "missing request for cpu in container" in Kubernetes HPA