ASP.NET Core health check reports Unhealthy in CI
The /health endpoint returned Unhealthy (HTTP 503) because a registered health check failed. In CI this is usually a database or dependency check that cannot reach its resource, not a bug in the app itself.
What this error means
A CI smoke test or deploy gate hits /health and gets 503 with a body naming the failing check, for example a DbContext check reporting the database is unreachable.
GET /health -> 503 Service Unavailable
{"status":"Unhealthy","entries":{"npgsql":{"status":"Unhealthy",
"description":"Failed to connect to 127.0.0.1:5432"}}}Common causes
A dependency check cannot reach its resource
A database or external-service health check fails because that dependency is not provisioned or not ready in CI.
The probe runs before the app is ready
The smoke test hits /health before startup or migrations finish, so a check that will pass shortly reports Unhealthy.
How to fix it
Provision the dependency and wait for readiness
- Start the database or dependency the check targets.
- Wait until the app and its dependencies are ready before probing
/health. - Use a liveness endpoint with no dependency checks for the initial readiness gate.
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = _ => false // liveness: no dependency checks
});
app.MapHealthChecks("/health/ready");Retry the probe with a timeout
Poll /health with a short retry loop so a slow-starting dependency does not fail the gate immediately.
for i in $(seq 1 30); do
curl -fsS http://localhost:5000/health && break
sleep 2
doneHow to prevent it
- Separate liveness (no deps) from readiness (with deps) endpoints.
- Provision and wait for dependencies before probing readiness.
- Poll the health endpoint with a bounded retry instead of a single request.