This Cloud Run error means a new revision never became ready: the container process started (or tried to) but nothing was accepting TCP connections on the expected port before the startup deadline. Cloud Run refuses to route traffic to it, and if this was your first deploy or you route all traffic to the new revision, the service is down. The container logs almost always show the real failure, and the fix is usually a one line change in how the app binds its listener.
The user-provided container failed to start and listen on the port defined by the PORT environment variable
What this error means
Cloud Run’s contract is simple: it sets the PORT environment variable inside the container, and your process must listen on that port on 0.0.0.0 within the startup probe window. The default port is 8080 and the default probe checks TCP connectivity. If the process crashes during boot, binds a different port, binds only to localhost, or takes too long initializing, the probe never succeeds and the revision is marked failed with this message. The error is the generic wrapper; the specific cause is in the revision’s container logs.
Common causes
- The app hardcodes a port (3000, 5000, 8000) instead of reading
PORT, or the framework default differs from the container port configured on the service. - The listener binds to
127.0.0.1orlocalhost, which is unreachable from the probe; it must bind0.0.0.0. - The process crashes on boot: missing environment variables or secrets, a failed database connection, an unhandled exception in initialization, or a bad module import.
- The image was built for the wrong CPU architecture, typically arm64 from an Apple Silicon laptop; Cloud Run runs amd64 (unless the service explicitly uses an arm64 configuration).
- Startup is legitimately slow (migrations, model loading, JVM warmup) and exceeds the startup probe budget.
- A wrong
ENTRYPOINTorCMD, so the container runs a shell or a one shot script and exits instead of starting the server.
How to fix it
STABILIZE first. If a previous revision worked, route traffic back to it while you debug the new one:
gcloud run services update-traffic my-service \
--to-revisions my-service-00042-abc=100 \
--region us-central1
- DIAGNOSE from the failed revision’s logs, which contain the crash output or show that nothing ever listened:
gcloud run services logs read my-service \
--region us-central1 \
--limit 100
A stack trace means the app crashed: fix that error (often a missing env var or unreachable dependency). No output at all after startup suggests the process is running but bound to the wrong port or address.
- Verify the contract locally by running the image exactly as Cloud Run does, with
PORTinjected:
docker run --rm -e PORT=8080 -p 8080:8080 gcr.io/my-project/my-app
curl -i http://localhost:8080/
- FIX the binding in the application. For example in Node.js:
const port = process.env.PORT || 8080;
app.listen(port, '0.0.0.0');
The same rule applies everywhere: gunicorn needs -b 0.0.0.0:$PORT, Spring needs server.port=${PORT}, and so on.
- If the image architecture is wrong, rebuild for amd64:
docker buildx build --platform linux/amd64 -t gcr.io/my-project/my-app .
docker push gcr.io/my-project/my-app
- If startup is genuinely slow, extend the startup probe and give boot more CPU, then redeploy:
gcloud run services update my-service \
--region us-central1 \
--cpu-boost \
--startup-probe tcpSocket.port=8080,initialDelaySeconds=10,periodSeconds=10,failureThreshold=30
How to prevent it
- Always read
PORTfrom the environment and bind0.0.0.0; never hardcode the listen address in an image destined for Cloud Run. - Build images for
linux/amd64in CI rather than on developer laptops. - Fail fast and loudly on missing configuration at boot so the log states exactly which variable is absent.
- Keep the boot path lean: open the listener first, defer heavy warmup, and let a readiness signal gate traffic.
- Test every image with
docker run -e PORT=8080in CI before deploying, since that one command catches most contract violations.
When to call a senior engineer
Call for help when the revision fails with no useful log output, when startup failures are intermittent and smell like a race between the app and its dependencies, or when a migration to Cloud Run keeps stalling on a legacy app that assumes a fixed port and local services. Erzon engineers can reproduce the container contract precisely, find the exact boot failure, and restructure startup so revisions deploy cleanly every time.
Related errors we fix
503: The service is currently unavailable (GCP) Fix this error → Google Cloud 429: Rate Limit Exceeded (GCP) Fix this error → Google Cloud PERMISSION_DENIED: The caller does not have permission Fix this error → Google Cloud could not connect to server: Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432? Fix this error → Want a senior engineer to just fix it?
Paste this exact error into the form. A senior engineer replies within one business hour with what is likely wrong and a flat quote. Triage is free.
Book a fix