Skip to content

Health check failed

The health-check stage runs last — after cdk deploy (and, for static sites, publish) has succeeded. It verifies the deployed URL actually serves your application, not just a reachable 200. Two distinct shapes can fail a health check, and they need different fixes.

The generated workflow does not retry a failed health check beyond its built-in attempts, and it does not deploy on top of a failed one — a failed attempt leaves your stack at the last successful deployment. Fix the cause, then re-run the deploy workflow to re-deploy.

1. Wrong HTTP status (the app is not answering)

Section titled “1. Wrong HTTP status (the app is not answering)”

The health check polls the live URL and expects a 2xx or 3xx. A 4xx/5xx, a connection error, or a timeout fails it.

The job log shows the target URL and the HTTP status lines (never a full response body — bodies can contain PII). Open the failed health-check job and read:

  • The target URL it polled.
  • The status codes it saw across attempts.
Symptom What it usually means
000 / 0000, connection error, timeouts The service isn’t reachable at that URL — wrong host, a load balancer still draining, or the service never came up
4xx A route is missing or misconfigured (missing front-controller, no matching route, auth wall on the checked path)
5xx The service started but is erroring on request (missing runtime dependency, a config/env var, a crashing worker)

Common causes: wrong URL/host in the live-URL output, environment variables your app needs at runtime (a missing or mis-typed env var is a frequent cause of 5xx), or the app shape (static vs container) not matching what is actually deployed.

2. Placeholder content (the 200 is not your app)

Section titled “2. Placeholder content (the 200 is not your app)”

This is the specific failure the health check exists to catch: the live URL returns a ScaleBop placeholder page (a 200 with placeholder body, or 200 - not deployed) instead of your application. That means your artifacts never replaced the placeholder — e.g. S3 sync was skipped, the bucket is empty, or the container image wasn’t pushed — so the bucket or service still serves the default placeholder.

If your failure code is the placeholder case, check that your artifacts were actually pushed: the S3 sync in the publish log for static sites, or Push image to ECR and Deploy CDK stack with the new image in the deploy log for container apps. If those show success but the placeholder is still live, force a re-deploy with the correct artifact.

  1. Confirm the URL and the HTTP behavior described above.
  2. Fix the cause (a runtime env var, a route, or a skipped artifact).
  3. Re-run the deploy workflow from ScaleBop’s Pipeline page or from GitHub Actions. A re-run deploys and health-checks your current commit again, and the previous attempt stays visible in deployment history.

Note: if you just added or changed a custom domain, the health check is run against the default AWS URL while custom-domain DNS and HTTPS settle. DNS-specific symptoms (NXDOMAIN, a domain that resolves but returns 403, or cert warnings) are covered in DNS propagation.