Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

Docker Container Health Check Failed: Exited with status 1

Verified FixPython 3.10+Docker 25.0+ / Docker ComposeSilo: devops

Quick Fix / Solution Rapide

Add start_period: 30s to allow the application time to boot before healthchecks begin, and verify that curl or wget is installed in the image.

Root Cause Analysis

This error occurs when Docker executes a container's configured HEALTHCHECK command and the probe command returns a non-zero exit code (status 1), causing Docker to mark the container status as unhealthy and triggering automated orchestrator restarts.

1. Missing start_period During Application Warmup

Web applications (like Django with database migrations or FastAPI with ML model loading) may take 15–30 seconds to boot up. If the healthcheck probe runs immediately at second 5, the server is not yet listening on the port, failing the check.

2. Missing curl or wget Utility in Minimal Docker Images

Using HEALTHCHECK CMD curl -f http://localhost:8000/health || exit 1 inside minimal images (like python:3.12-slim or alpine) fails because curl is not installed, returning command not found (exit code 127/1).

3. Binding to 127.0.0.1 Inside Container with External Healthcheck

If the application listens only on 127.0.0.1 while healthchecks probe container IP or vice-versa.

4. Healthcheck Endpoint Returning 500 or Database Disconnected

If /health performs a database ping and the database container is still starting up, the healthcheck correctly reports failure.

Reproduction Code (MCVE)

Example: Bug Reproduction
# **Note de reproductibilité :** Dépendant de l'environnement d'exécution du conteneur.
raise OSError('Container health check failed: command "curl -f http://localhost:8000/health" exited with status 1 (connection refused)')

Solution 1: Use Built-In Python One-Liner for Zero-Dependency Healthcheck

Use Python's native urllib.request in healthchecks to avoid installing external tools like curl.

Example: Recommended Solution
print('Dockerfile Zero-Dependency Healthcheck:')
print('HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=3 \\')
print('    CMD python -c "import urllib.request; urllib.request.urlopen(\"http://127.0.0.1:8000/health\")" || exit 1')

Solution 2: Configure Docker Compose start_period and Retries

Provide a grace period in docker-compose.yml for database migrations and initialization.

Example: Alternative Solution
print('docker-compose.yml healthcheck configuration:')
print('services:')
print('  web:')
print('    healthcheck:')
print('      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen(\'http://127.0.0.1:8000/health\')"]')
print('      interval: 10s')
print('      timeout: 3s')
print('      retries: 3')
print('      start_period: 20s')

A common mistake is having /health endpoints execute slow, heavy database queries. Health checks run every few seconds; heavy queries cause database connection pool exhaustion. Keep health check endpoints lightweight (e.g. SELECT 1). Edge cases occur with Docker Compose depends_on: use condition: service_healthy to guarantee that services wait for database health before starting. Contrast this error with Container exited with code 137, which indicates an Out-Of-Memory (OOM) kill.