Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Troubleshooting & FAQ

Symptom-first answers to the problems people hit most often. Each entry explains why it happens and what to do about it. The examples use an Organization acme, Project shop, Environment production, and an app named web.

My build is stuck or failed

Why it happens. Every push to your app’s repository starts a build. While it runs, the deployment shows as Building; if the buildpack cannot build your code, it moves to Failed and the entry carries the build’s error message. A build that finishes but does not ship is not stuck — if the Environment’s Automatic deployment setting is off, the build stops at Built (“Built. Waiting to be deployed (auto-deploy is off)”) until you deploy it yourself.

What to do. Check the deployment history — in the dashboard, the app’s Deployments tab; from the CLI:

paas releases -o acme -p shop -e production
  • Failed — the REASON column of paas releases (and paas deploys info <N> for the full timeline) gives the failure message; paas ps, paas watch and the log stream report it too. paas logs --build <N> -a web prints that deployment’s saved build log (kept for the newest 1000 deployments in the Environment). The message says which kind of failure it was:

    • A problem in your app. The message names the build step that failed and, where it can, the error — for example:

      The build step failed: failed to build: exit status 1. Fix the error in your app and push again.
      

      Two others point at the repository itself: “The repository has no code yet. Push a commit and the build starts automatically.” and “The branch to build wasn’t found in the repository. Push it, or check the app’s branch setting.”

      Fix the code and push again; a new push starts a fresh build. When the message names the step but no error, the usual cause is an app that doesn’t match its framework — check it builds locally with that framework’s standard commands. Supported Frameworks lists what each framework expects, and Builds can’t reach a private address covers dependencies that fail to download.

    • A problem on the platform’s side. The message reads:

      The build could not complete because of a problem on our side, not in your app. Push again to retry; if it keeps happening, contact support.
      

      Your code is not at fault. Retry by pushing again — an empty commit is enough:

      git commit --allow-empty -m "Retry build"
      git push paas main
      

      If it keeps happening, contact support.

  • Built (“Waiting to be deployed (auto-deploy is off)”) — the build succeeded and is waiting for you. Ship it:

    paas deploy -o acme -p shop -e production -a web
    
  • Building for a long time — builds run from source and can legitimately take a while. While no instance is running yet, the app’s instance list also reports the build state and any message:

    paas ps -o acme -p shop -e production -a web
    

    The platform doesn’t let a build hang forever. A build that hasn’t started 30 minutes after the push fails with “The build didn’t start. Push a new commit, and contact support if it keeps happening.”; one that disappears mid-build fails with “This build stopped and won’t finish. Push again to start a new one.”; and one still running after 3 hours is marked failed with “This build took over 3 hours without finishing, so it was marked failed. If it does finish, it will still be deployed; otherwise push again.” The Organization’s owner is also emailed about a recent push whose build stalls this way.

Builds can’t reach a private address

Why it happens. Builds can reach the public internet but not private network addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 100.64.0.0/10) or the platform’s internal services. A build step that fetches from one — a private package mirror, a git dependency on an internal host — fails with a connection timeout or “could not resolve” error.

What to do. Serve the dependency from somewhere reachable over the internet (a public registry, or a private registry with a public address and credentials), or vendor it into your repository. See How Builds & Deployments Work.

Logs say the image is still building

Why it happens. Right after a push there is nothing to show logs from: your new version has no running instance yet. Instead of a bare “not found” error, the log stream reports where things stand:

  • the image is still building,
  • the build failed (with the build’s error message),
  • the build hasn’t started yet, or the build finished but no instance is running yet — either it hasn’t been deployed (Automatic deployment is off) or the rollout is still in progress.

What to do. Match the message:

  • Still building — wait, then retry paas logs -a web --tail (or the dashboard’s Logs tab).
  • Build failed — see the entry above: the message says whether to fix your code or retry.
  • Built but no instance running yet — if the Environment’s Automatic deployment is off, run paas deploy -a web to ship the build; otherwise the rollout is in progress — watch it with paas status -o acme -p shop -e production -a web.

Once the first instance is running, logs flow normally. See Logs for the full log tooling.

My deployment failed or was rolled back

Why it happens. A probed instance must pass its health check before taking traffic. If the rollout makes no progress toward healthy new instances for 5 minutes, the deployment fails, and with automatic rollback on (the default) the previous version is put back. The deployment’s reason says what went wrong:

  • “Your app keeps exiting (exit code N)”, with its last output — the app crashes on start. Read the output, fix the code, and push again.
  • “Health check /health returned 404”, or “… timed out” — make the health check path return a success response, quickly and without login.
  • “Health check /health couldn’t connect (is your app listening on $PORT?)” — bind your server to the port in $PORT.
  • “A required setting or secret is missing” — check the container configuration and secret bindings. A missing app secret may instead leave its variable absent; validate required settings at startup.
  • “The new version didn’t become healthy within 5 minutes: …” — the detail after the colon says why.
  • “There wasn’t enough free capacity on our servers to start the new version” — a problem on the platform’s side, not in your app; deploy again later.

What to do. Fix what the reason names and push again. See Deployments, Health Checks & Rollback.

My app is not seeing a new secret

Why it happens. Secret values are injected into an instance when it starts. Linking a variable to a secret redeploys the app, and changing a secret’s value restarts every linked app within seconds — but creating a secret does not. If the app was already running with a variable linked to a secret that did not exist yet (you deleted and re-created the secret), its instances keep running without the value until they are replaced.

What to do. Restart the app so fresh instances come up with the secret in place:

paas restart -o acme -p shop -e production -a web

Or click Restart on the app’s page in the dashboard. The restart is rolling, so a multi-instance app keeps serving traffic. (A singleton app stops its one instance before starting the new one, so expect a few seconds of downtime.) Confirm the binding itself is correct on the app’s environment variables (a variable referencing the secret) — see Managing Secrets and Environment Variables.

I can’t scale — autoscaling is on

Why it happens. While autoscaling is enabled, the autoscaler owns the replica count; a fixed value you set would immediately be fought over. The platform therefore rejects paas scale with a conflict error while autoscaling is on, and the dashboard replaces its replica controls with a note that the count is managed by the autoscaler.

What to do. Turn autoscaling off — Disable on the app’s page in the dashboard, or paas apps update web --autoscaling false -o acme -p shop -e production — then either re-enable it with a new range (min/max replicas and target CPU) or set a fixed count:

paas scale 3 -o acme -p shop -e production -a web

The same happens for a singleton app, with its own message: turn singleton off first (paas apps update web --singleton false -o acme -p shop -e production), or, if d2o-paas.yaml sets singleton: true, change it there.

See Scaling & Autoscaling.

I got a “limit exceeded” error

Why it happens. Your Organization’s plan sets limits on what it can hold, and every write that would consume capacity — creating a resource, scaling up, adding an Environment — is checked against them. A request over the limit is rejected with a LIMIT_EXCEEDED error that names the limit, your plan’s maximum, and your current usage.

What to do. Check your Organization’s effective limits and current usage in the dashboard (any member can see them). Free capacity by removing things you no longer need, or talk to whoever operates your platform about your Organization’s plan. Enforcement only applies to new writes: nothing you already have is ever deleted because of a limit. See Plans, Limits & Usage.

My app scaled to zero, or my bucket stopped serving publicly

Why it happens. Separately from the capacity limits above, your Organization also has a monthly transfer allocation — a budget for the public network traffic your Web Applications actually send and receive each month. If usage for your Organization, a Project, an Environment, or a single Resource stays over that budget, the platform automatically scales every Web Application and Background Worker covered by it to zero replicas, and switches every public Object Storage bucket covered by it to private. An affected app or worker shows status Blocked instead of Stopped, and its Restart button is disabled with the reason underneath (over the monthly transfer allocation — starts again automatically when usage is back under budget, normally at the start of next month — plus a link to your usage). An affected bucket’s Visibility shows Private — blocked instead of Public, its public URL is hidden (it wouldn’t work while blocked), and a note underneath explains why and that it’ll be public again once unblocked. The paas apps/buckets list and info commands show the same thing in their status text.

What to do. The Organization’s owner gets an email when this happens (“Resources blocked: over monthly transfer budget”) and another once it’s lifted. If you have Owner or Admin access, the audit log records a block entry naming the resource. The block clears itself automatically once usage is back under budget — normally when the next calendar month starts — or sooner if whoever operates your platform installation raises the allocation. There is nothing to scale, restart, or reconfigure to force it back on early. See Monthly transfer allocation for what counts and the alert thresholds leading up to it.

I’m getting “429 Too Many Requests”

Why it happens. The platform’s API limits how fast each client can send requests. A script or CI job that loops over many apps, or retries in a tight loop, can go over. The response is 429 with a Retry-After header giving the seconds to wait.

What to do. Wait the Retry-After time, then continue more slowly — add a delay between requests, and back off on repeated 429s rather than retrying immediately. See API rate limits for the numbers.

I can’t sign in, or my invitation isn’t working

Why it happens. The platform is invitation-only. Signing in does not create an account by itself — you need a pending invitation for your email address. When someone invites you:

  • New to the platform — you receive an email asking you to set a password; once set, you land on the invitation accept page.
  • Already have an account — you receive an invitation email with a link to the accept page instead (no password reset).

You must be signed in to accept. A Project invitation is also rejected — both when it is created and again when you try to accept it — if your email already belongs to a member of that Organization; members get Project access through groups instead.

What to do.

  • No account after signing in? Ask an Organization Owner or Admin to invite your email address, then follow the email’s link.
  • Invitation email never arrived, or the link expired? Ask the inviter to click Resend next to your invitation in the Organization’s or Project’s Members settings. Invitation links work for 7 days; a resend sends a fresh one.
  • Invited to a Project you can’t accept because you’re already in the Organization? Ask an Owner or Admin to grant your group access to the Project instead — see Groups & Project Permissions.

See Inviting People.

I can’t delete an environment

Why it happens. The Environment is marked Protected. Protection exists exactly for this: a protected Environment cannot be deleted at all, so a slip of the mouse can’t take out production.

What to do. If you really mean to delete it, remove protection in the Environment’s settings first, then delete. Deleting an unprotected Environment permanently removes it and all of its resources, and asks you to type the Environment name to confirm. See Organizations, Projects & Environments.

My app has no URL

Why it happens. Two common causes:

  • It’s a Background Worker. Workers run without a public URL by design — they receive no HTTP traffic. Only Web Applications get one.
  • It hasn’t deployed yet. The address only answers once a deployment is live — check the app’s Deployments tab, and see Supported Frameworks for the files each framework’s build needs.

What to do. If the code needs to receive HTTP requests, create it as a Web Application. For a Web Application, push (or click Deploy latest on its GitHub/GitLab link), and once the deployment succeeds the public URL answers; it’s shown on the app’s page in the dashboard. To serve it on your own domain instead, see Custom Domains & TLS.

“several apps build from this directory (…) — pass -a”

Inside an Environment’s shared repository the CLI picks the app from your working directory. When more than one app builds from the same directory (for example two apps at the repository root that run different processes), it cannot choose — name the app:

paas logs --tail -a bot

“no app builds from this directory — pass -a”

Inside an Environment’s shared repository, your working directory doesn’t match any shared app’s source directory, and it isn’t the repository root either — so the CLI has nothing to infer from. (If the checkout also has a leftover per-app paas remote from before the shared remote existed, and that remote points at the same org/project/Environment you’re actually targeting, the CLI falls back to that remote’s app instead of showing this error — you’ll only see it when there’s no such fallback. It never falls back on the ambiguous case above, since guessing among several matches would be worse than asking.) Name the app:

paas logs --tail -a bot

git push over HTTPS says “Authentication failed”

An HTTPS push token expires after 30 days. Get a fresh one and push again — for the Environment’s shared remote:

paas git remote --https

For an app with its own repository, add -a APP. In the dashboard, use Regenerate token on the Git remote panel. Pushing over SSH avoids this entirely.

git push says “This environment deploys from GitHub …”

This environment deploys from GitHub acme/shop@main. Push there instead, or allow direct pushes in the environment's settings.

(An app-linked target says “This app deploys from … in the app’s settings.”) The Environment or app deploys from a linked GitHub or GitLab branch, and direct pushes are off. Push to the linked branch instead, or turn on Allow direct pushes on the repo link (Environment or app settings). See Deploy from GitHub or GitLab.

Next steps