Skip to main content

Troubleshooting deploys

A Vessl deploy runs in clear phases: clone → build → release (post-deploy) → canary health check → traffic swap. When something fails, the deploy logs (the deployment drawer) tell you which phase and why. This page maps the common failures to fixes.

A failed deploy never takes you down

Vessl health-checks the new version as a canary before swapping traffic. If any phase fails, your previous version keeps serving — so you can fix and redeploy without downtime.

Clone phase

could not read Username / "Repository not found" Vessl can't authenticate to your repo. The GitHub App isn't installed on the account that owns the repo, or its access was revoked.

  • Re-connect under Integrations on the owning account/org (for your-org/app, install on your-org).
  • If you recently reconnected, Vessl auto-relinks to the new installation for the same account — just redeploy.

Clone times out on a very large repo Large histories can be slow to clone. Push a slimmer history, or contact support if you regularly deploy big monorepos.

Build phase

Nixpacks can't resolve your language/runtime version Nixpacks reads your project files to pick the toolchain. Make sure they agree:

StackWhere the version comes from
Nodepackage.json engines.node
PHPcomposer.json require.php floor
Python.python-version / pyproject.toml
Ruby.ruby-version / Gemfile
PHP version comes from composer.json, not a UI setting

Nixpacks picks the PHP version from your composer.json require.php floor and your lockfile. If your composer.lock was resolved against a higher PHP than your require allows, composer install fails. Align require.php with the PHP your lockfile actually needs, then commit both.

Unsupported Gradle version (modern Java/Spring) Nixpacks doesn't support the newest Gradle. Pin a supported Gradle version in your project, or build with a Dockerfile.

Build needs a flag or an env var at build time

  • Add --build-arg-style values with Build Args (passed to your Dockerfile).
  • Override the build with a Build Command when the default doesn't fit.
  • Only env vars with public prefixes are baked into the image at build time; secrets (DB passwords, app keys) are injected at runtime, not build time.

Monorepo — wrong directory built Set the Root Directory on the app to the subfolder that contains the app (e.g. backend). Vessl builds from there.

Release (post-deploy) phase

The release command runs once, after build, before traffic swaps — this is where migrations belong. If it fails (e.g. a bad migration), the deploy fails and your old version stays live.

  • Put migrations/seeders here, not in your start command. See Database migrations & seeding.
  • A long first-time migration can exceed the readiness window — split it, or make sure the database add-on is ready first.

Canary / health-check phase

Health check fails with HTTP 500 The app built and started but errors on the health check. Usual causes:

  • A missing environment variable — set it on the app and redeploy.
  • A database it can't reach — confirm the add-on is attached and you redeployed after adding it (see Databases & add-ons).
  • A runtime crash on startup — read your app's own error in the deploy logs.

Health check times out, but the app is slow to boot Frameworks that migrate or warm caches on boot can exceed the default window. Make sure heavy work runs in the release phase, not on every container start.

The wrong command runs / the app starts in a REPL For Dockerfile builds, Vessl appends your Start Command to docker run — make sure it actually starts your web server (e.g. node server.js, gunicorn ...), not the image's default CMD. If you set no start command, the image's CMD runs, which for some base images drops into an interactive shell.

Deploy seems stuck

Deploys are processed by a dedicated worker and have generous timeouts. If a deploy looks stuck:

  • Watch the live logs — long builds (heavy Rails/Vite, large Docker images) genuinely take several minutes.
  • A first deploy holds a per-server lock for the build; a second deploy to the same server queues behind it.
  • You can Cancel a deploy; the app returns to its previous state.

Still stuck?

Capture the failing phase and the last lines of the deploy logs, then reach out via the dashboard. The phase label plus your app's own error message is usually all that's needed to pinpoint it.