Troubleshooting Git Deployments: Stuck, Failed or Not Triggering

Updated November 2, 2026 · 9 min read

Summarize with:
Share:

A Git deployment can go wrong in a few different ways: stuck in progress, failing partway through, or simply not starting when you push. Each one has a different fix. When a deploy fails, the notice on the Deployments page tells you why, and the deployment logs give you the detail.

Start with the deployment logs

Before trying anything else, open the site’s deployment logs from the Deployments page in the site menu. They show which stage failed — cloning the repository, running the build, or starting the app — and that determines which section below applies.

If the latest deploy failed, read the failure notice on that page first. It names the failed step and shows the part of the output around the first error, so you often won’t need the full log.

See why a deploy failed

When a deploy of a Git site fails, xCloud shows the notice Deploys of this site are failing on the site’s Deployments page, above the list of deployments. The notice stays until a deploy succeeds.

Step 1: Open the Deployments page

Open the site and click Deployments in the site menu. You can also click View Deployments in the failure email.

Click ‘Deployments’ in the site menu to see the ‘Deploys of this site are failing’ notice above the list

Expected result: the notice appears below the summary of the latest deployment. If there is no notice, check the status of the latest deployment in the list. If it shows Failed and there is no notice, the deploy may not have reached the server: see When a deploy never reached the server.

Step 2: Read the notice

The notice tells you what went wrong and where it stopped.

Part of the notice What it tells you
Summary The cause in plain words.
Failed step Where the deploy stopped: Pull latest code, Deploy script, Build or Start. It is left out when no step can be named.
failing since How long the site has been failing.
failed 2 more times with the same reason How many more times the same failure happened. It appears only after a repeat.
Output lines About 40 lines of output around the first error. Values that look like passwords and keys are hidden.

The summary comes from matching the output against known errors, so an earlier warning can point it at the wrong cause. If the summary and the output disagree, go by the error line just above the point where the deploy stopped.

Step 3: Fix the cause and deploy again

Use the failed step to choose the fix:

Failed step Where to look
Pull latest code Clone fails
Deploy script The command named in the summary or in the last error lines of the output. Edit it under Deploy Script on the site’s Git page.
Build or Start Build or start fails

Then click Deploy Now at the top of the page. If you see Check & Deploy instead, click that. On the free plan there is no Deploy Now button, so push a commit to the site’s branch (Enable push to deploy must be on in the site’s Git settings), or change a setting on that page and click Save and deploy.

Expected result: the notice goes away once the deploy succeeds. xCloud does not send an alert when a site recovers. If the deploy fails again, the notice stays and shows the new result.

If the summary says only “The deploy failed.”

This means the cause is not in your site’s code or settings, so the notice shows no output lines and the alerts leave out the cause. Contact our support team and tell them which site is affected.

Deploy failure alerts

Your team hears about a failing site by email and through any notification channel you have connected.

Where What the alert includes
Email The subject Deployment Failed, the summary, the failed step, the output lines and a View Deployments button. For the full log, open the Deployments page.
Slack, Telegram, WhatsApp and in-app alerts The summary, the failed step, up to 10 lines of the cause and a link to the site’s Deployments page.

You are told when something changes, not on every repeat:

What happens Do you get an alert?
A site starts failing Yes
It fails again for the same reason No, the count in the notice goes up
It fails with a different kind of error Yes
The same kind of failure has a new reason Yes, opening with “The deploy failed for a new reason.” At most once an hour per site
A deploy succeeds No, the notice goes away

To connect a channel or choose what you receive, see Slack, Telegram, WhatsApp and turning off notifications.

When a deploy never reached the server

A deploy that could not reach the server does not count against your site, because nothing ran there. You get no failure alert, and this attempt adds no failure notice. If an earlier deploy was already failing, its notice stays. The attempt still shows as Failed in the Deployments list, and its log says “Nothing ran on the server”.

Instead, xCloud tries the same deploy again after 2 minutes, then 5, then 8, which is 15 minutes in all. If you or a push start a newer deploy in the meantime, it replaces the retry.

If the third retry can’t reach the server either, your team gets one server disconnected notice, at most once per server in 6 hours. Check that the server is online and connected, then deploy again.

Stuck “in progress”

If a deployment still shows in progress after about five minutes, it’s likely hung rather than genuinely still running. Use the site’s Check & Deploy action: it checks whether the previous deployment process has actually stopped. If it has, xCloud marks that attempt as failed, releases the deployment lock, and starts a fresh deployment.

A deploy waiting on a retry looks different: between tries, the Deployments list shows the attempt as Failed with no new failure notice, for up to 15 minutes. See When a deploy never reached the server.

Clone fails

A failed clone falls into one of three categories, and they need different fixes:

  1. Missing branch — the log shows something like “Remote branch … not found.” Fix: set the deployment to point at a branch that actually exists in the repository.
  2. Access error — the log shows “Permission denied (publickey)” or “repository not found.” This is not a branch problem, and changing the branch will not fix it. Fix the deploy key or reconnect the Git provider instead (see below).
  3. Network error with no Git-specific message — retry the deployment once. If it fails again the same way, the problem is the server’s outbound connection to the Git host, not the repository or credentials.

Fixing a missing or rejected deploy key

  1. Open the site’s Git settings.
  2. Click the button to configure the deploy key.
  3. If xCloud can add the key to the repository automatically, it will. If it can’t (for example, you don’t have admin rights on the repository), copy the public key it shows you and add it to the repository yourself as a read-only deploy key.
  4. Click Verify connection.
  5. Redeploy.

Confirm the server can reach the Git host over SSH on port 22 — a network block there produces the same kind of access error as a bad key.

Build or start fails

  • .env file path points at a folder, not a file. The path is joined to /var/www/<site>/ and needs to resolve to an actual file — .env for a normal project, or something like backend/.env for a monorepo. Pointing it at a bare folder name such as backend fails with an error like “Is a directory.”
  • Build commands. Check the build command for typos, a missing dependency install step, or a script that assumes a different working directory than the one xCloud runs it from.
  • Deploy script. If the failed step is Deploy script, see Deploy script stopped at a failed command.

Deploy script stopped at a failed command

New Git sites stop the deploy script at the first command that fails and mark the deployment as failed. This keeps a half-finished deploy from showing up as a success. The switch that controls it is Stop the deployment when a command fails.

The script only runs when Run this script after every site deployment is on.

Site What happens when a command fails
Created on xCloud v2.8.8 or later The switch is on. The deploy stops at that command.
Created before v2.8.8 The switch is off. The script carries on to the end, and a failed command in the middle doesn’t fail the deployment.
Cloned from another site The clone copies the switch from the site it came from.

Turn the setting on or off

If your site was created before v2.8.8, check your script first. A command that has been failing unnoticed will stop the deploy once the switch is on.

Step 1: Open your site and click Git in the site menu. The Git Settings page opens.

The Git entry in the site menu, which opens the Git Settings page

Step 2: Under Deploy Script, turn Stop the deployment when a command fails on or off.

The ‘Stop the deployment when a command fails’ switch under the Deploy Script field in Git Settings

Step 3: Click Save Changes. xCloud shows “Git settings updated successfully.” The change applies from the next deployment. To deploy straight away, click Save and deploy instead.

Find the command that failed

Step 1: Click Deployments in the site menu. After a failed deploy, the Deploys of this site are failing notice names the line, the command and its exit code.

Step 2: Select the failed deployment in the list. The panel shows which step failed, such as Deploy script. Click Jump to line and the line number shown on the button (for example, Jump to line 12) to go to the error in the log. The failing lines are highlighted:

XCLOUD_DEPLOY_SCRIPT_FAILED: line 2: exit 127: ./scripts/clear-cache.sh
ERROR: the deploy script failed for example.com (exit 127).

The highlighted failure lines in the Deploy script step of the deployment log

The line number counts from the top of your Deploy Script field. The shell’s own error just above it can show a number one higher, so go by the XCLOUD_DEPLOY_SCRIPT_FAILED line.

If your script starts with a set line, such as set -e, the XCLOUD_DEPLOY_SCRIPT_FAILED line doesn’t appear. Look at the last output from your script in the log instead.

Step 3: Fix the command, then click Save and deploy on the Git Settings page. The new deployment appears in the list as successful once every step finishes.

If the fix is in your repository, push it. The push starts a deployment when Enable push to deploy is on. On paid plans you can also click Deploy Now.

What your site runs after a stopped deploy

xCloud pulls your code before it runs the deploy script, so the new files are already in the site folder. A Node.js site keeps its current build only if the script stopped before your build command ran. If the build finished first, your site’s files have already changed. A site that serves files straight from the folder, such as a PHP site, can pick up those files right away, so fix the script and redeploy soon. The Deployments page may still say your site is live on the previous version, but on these sites the new files are already in place.

Write a script that handles failures

Use these patterns when a command is allowed to fail:

You want Write
One command may fail ./scripts/clear-cache.sh || true
A step runs only when a file exists if [ -f ./scripts/seed.sh ]; then ./scripts/seed.sh; fi
The whole script handles failures itself set +e or set -e as the first line

For example, this script allows the cache step to fail and skips the seed step when the file is missing. Any other failed command still stops the deploy:

npm install
./scripts/clear-cache.sh || true
if [ -f ./scripts/seed.sh ]; then
  ./scripts/seed.sh
fi
npm run build --if-present

Keep these in mind:

  • Only use || true on optional steps. On a required step, it hides the failure you want to see.
  • If the first command in your script is a set line, the switch no longer stops the script. Blank lines and comments above it don’t change this. Your script decides what happens when a command fails. With set +e, a failed command doesn’t stop the deploy. If the last command in the script fails, the deployment is still marked as failed.
  • Any set line at the top counts, even set -x. A script that starts with set -x no longer stops at a failed command. If the last command in the script fails, the deployment is still marked as failed.
  • You only see XCLOUD_DEPLOY_SCRIPT_FAILED when the switch stops the script. It doesn’t appear when your script starts with set -e, even though the script still stops at a failed command.
  • When the switch is on and your script has no set line at the top, a failure anywhere in a pipeline counts. In npm test | tee test.log, the deploy stops if npm test fails, even though tee succeeds. If you start with set -e, add -o pipefail to get the same result.
  • Some commands exit with an error when they find nothing. For example, grep fails when there’s no match. Add || true if that’s a normal result.

For developers

The Public API exposes this switch as deploy_script_fail_fast on /api/v1/sites/{uuid}/deploy-config. See Deploy Git Projects with the Public API and MCP.

Auto-deploy not triggering on push

If pushes to the branch aren’t kicking off a deployment at all:

  • Check that the webhook is still registered on the Git provider’s side — it can be removed if repository permissions changed or the app was disconnected and reconnected.
  • Reconnect the Git provider integration if the connection itself looks stale.
  • Confirm you’re pushing to the branch the site is actually configured to deploy from.

What you can’t change after the site exists

Site type, repository, domain and database can’t be edited on an existing site. If any of those needs to change, the fix is to delete the site and create it again with the right settings from the start — not to try to work around it in the current site.

What to send support

  • The site domain and which app type it is (static, Node.js, Laravel, custom Docker).
  • The exact error text from the deployment log.
  • Which stage failed: clone, build, or start. The Failed step in the notice tells you this.
  • Whether this ever worked before, and if so, what changed (branch, repository access, server).

Still stuck? Contact our support team for any of your queries.

For developers

To read the same failure details from a script or an AI agent, see read why a deploy failed in the Public API and MCP guide.

Frequently asked questions

Why did I get only one alert when my deploy failed several times?

xCloud tells you when a site starts failing or fails for a different reason, not on every repeat. Repeats of the same reason only add to the count in the notice on the Deployments page. No alert is sent when the site recovers: the notice goes away after the next successful deploy.

My deployment says ‘Permission denied (publickey)’. What do I do?

This is an access error, not a branch problem — changing the branch won’t help. Go to the site’s Git settings, configure the deploy key (or add the public key to the repository yourself as a read-only deploy key if xCloud can’t add it automatically), click Verify connection, then redeploy.

My build fails with ‘Is a directory’. What’s wrong?

Your .env file path points at a folder instead of a file. It’s joined to /var/www//, so it needs to end in a file name — .env, or something like backend/.env for a monorepo — not just a folder name like backend.

Can I change the repository or branch on an existing site after it’s created?

Site type, repository, domain and database can’t be changed on an existing site. If you need a different repository or a different site type, delete the site and create it again with the correct settings.

Why did my deployment start failing after I turned on ‘Stop the deployment when a command fails’?

A command in your deploy script was already failing, and the script used to carry on past it. Open the failed deployment to see the line and the command, then fix the command or add || true if it’s allowed to fail.

Can I let one command fail without stopping the deployment?

Yes. Add || true after that command, for example ./scripts/clear-cache.sh || true. The rest of the script still stops at any other failed command.