Skip to content

Troubleshooting

Quick fixes for the issues we see most often. Each entry starts with the symptom you’re seeing, so scan the headings for yours. If none of these match, contact support from the dashboard and include your service name and what you tried.

Symptom: myapp.com loads fine, but www.myapp.com shows a security warning (“Your connection is not private”) or an error page.

Cause: The www variant of your domain isn’t set up. It needs its own DNS record and redirect.

Fix:

  1. Open your service → Domains tab
  2. On your domain’s card, make sure the www redirect toggle is on
  3. If ZevCloud manages your domain’s DNS, that’s it — it’s live within a minute
  4. If you manage DNS elsewhere, add the www record shown in the dashboard at your DNS provider, then wait for the deploy the toggle triggers

See Custom Domains → www Redirect for details.

”Your connection is not private” right after adding a domain

Section titled “”Your connection is not private” right after adding a domain”

Symptom: You just added a custom domain and the browser shows a certificate warning.

Cause: The SSL certificate is issued automatically after DNS verification, which takes a minute or two.

Fix: Wait 1-2 minutes and refresh. If it persists beyond ~10 minutes:

  • Confirm your DNS records match what the Domains tab shows (use the DNS button on the domain row)
  • If your DNS is on Cloudflare, make sure the record is “DNS Only” (gray cloud), not “Proxied”
Section titled “Pages 404 when refreshed or opened from a direct link”

Symptom: Your React/Vue app works when navigating from the home page, but refreshing on a route like /dashboard (or sharing that link) shows a 404.

Cause: Client-side routing needs the server to serve index.html for every route. Without that fallback, only / exists as a real file.

Fix: Open Service Settings → Build & Deploy, make sure Static site is on, then enable SPA (Single Page Application) and redeploy.

”Bad Gateway”, or the service shows Running but no endpoint responds

Section titled “”Bad Gateway”, or the service shows Running but no endpoint responds”

Symptom: The build and deploy both succeed, the logs show your app started normally, the dashboard says Running — and every URL returns Bad Gateway. Health checks may even be passing.

Cause: Your app is listening on a different port from the one configured on the service. Traffic is sent to the port in your service settings; if nothing is listening there, you get Bad Gateway no matter how healthy the app is. This is the single most common cause of “it deployed but nothing works”.

Fix:

  1. Open the Logs tab and find the line where your server starts. It almost always names the port — for example Uvicorn running on http://0.0.0.0:8000.
  2. Go to Service Settings → Build & Deploy and set Port to that number.
  3. Redeploy. A restart is not enough — the routing is applied when the container is rebuilt, so a restart will leave the old port in place.

Default ports, if you haven’t set one explicitly in your code:

FrameworkPort
FastAPI / Uvicorn8000
Django8000
Flask / Gunicorn8000
Go8080
Node, Express, NestJS3000
Next.js, Nuxt, Remix, SvelteKit3000
Ruby on Rails3000
PHP / Laravel80

I can’t connect to my database from my own machine

Section titled “I can’t connect to my database from my own machine”

Symptom: The connection string on the database’s Overview page works from an app deployed on ZevCloud, but times out or is refused from psql, TablePlus, or a local dev server.

Cause: New databases are private by default. They’re reachable from services you deploy on ZevCloud, and not from the public internet — which is the safe default, not a fault.

Fix: Open the database → Access & Connection → turn on public access. You’ll get a separate public host and port to use from outside. Keep using the internal URL for apps deployed on ZevCloud: it never leaves our network and is faster.

Public access is available on paid database plans. If the toggle is unavailable, the plan is the reason and the dashboard links to the upgrade.

My environment variable change didn’t take effect

Section titled “My environment variable change didn’t take effect”

Symptom: You added or edited a variable, but the running app still uses the old value.

Cause: Environment variables are applied when a service is built, so a change doesn’t reach a container that’s already running.

Fix: Redeploy the service. You can make several variable changes first — one deploy applies them all. The dashboard shows a reminder while you have unapplied changes.

My API is running but every route returns 404

Section titled “My API is running but every route returns 404”

Symptom: The service is up and reachable, but requests return 404 Not Found — including the root URL /.

Cause: Most API frameworks don’t define a route for / unless you write one. A 404 here means routing is working correctly and your app simply has nothing at that path. This is different from Bad Gateway, which means traffic never reached your app at all.

Fix: Request a path your app actually defines. If you’re using FastAPI, the interactive docs are the quickest check:

  • FastAPI — /docs (Swagger UI) or /redoc
  • Django REST Framework — the path in your urls.py, often /api/
  • Express / NestJS — whichever prefix you registered, often /api

If /docs loads but your own routes 404, check that your routers are actually included in the app, and that you’re calling the right prefix. If you deployed from a monorepo, also confirm the Base Directory points at the folder containing your app, not the repository root.

Vite / React deploy fails with a port or health check error

Section titled “Vite / React deploy fails with a port or health check error”

Symptom: The build succeeds but the deploy ends in “Failed”, often mentioning ports or health checks.

Cause: Client-rendered apps don’t run a server, so there’s nothing listening on a port for the platform to route to.

Fix: Enable Static site in Service Settings → Build & Deploy (or during creation). Your build output is then served directly as files — no port involved. See Static Sites & SPAs.

Symptom: The deploy shows as Ready, but visiting the site shows a blank page or a 404.

Cause: For static sites, the Publish Directory doesn’t match the folder your build actually produces.

Fix: Check your build tool’s output folder (Vite: dist, Create React App: build, Astro: dist) and set it as the Publish Directory in Service Settings → Build & Deploy, then redeploy.

Symptom: A push to your repository didn’t trigger a deployment.

Work through these in order:

  1. Branch — auto-deploy only fires for the branch configured on the service. Check Service Settings.
  2. Monorepo folder — if the service has a Root Directory set, pushes that don’t touch that folder don’t redeploy it. That’s by design.
  3. Open invoice — deploys are held while the service has an unpaid invoice. The Deployments tab shows a “Held” entry; settle the invoice and push again (or hit Deploy).
  4. Unrecognized committer — pushes from someone who isn’t a linked member of your team are queued as pending approval instead of deploying. Approve them from the Deployments tab.

The Free plan is greyed out when creating a service

Section titled “The Free plan is greyed out when creating a service”

Symptom: In the plan picker, the Free plan can’t be selected and a notice mentions a free tier limit.

Cause: Each team can run a limited number of free services at a time.

Fix: Upgrade one of your existing free services to a paid plan, or delete one you no longer use. The picker unlocks immediately.

Symptom: Code that sends mail via SMTP times out.

Cause: Direct SMTP ports are blocked platform-wide to prevent abuse.

Fix: Use your email provider’s HTTPS API instead (Resend, Mailgun, Postmark, SendGrid all offer one). HTTPS traffic is unrestricted. See outbound network restrictions.

Build output missing for an old deployment

Section titled “Build output missing for an old deployment”

Symptom: Opening an older deployment shows a note that its build output is no longer available.

Cause: Only recent build history is retained on the build infrastructure.

Fix: Trigger a new deploy — its output appears in full. The old deployment’s metadata (commit, status, timing) remains in the list.