Orbit

A Transfer at Our End Failed

If your deployment says A transfer at our end failed, we could not move a file your build needed, and the file was one we are responsible for moving. That is a fault at our end. Nothing in your…

If your deployment says A transfer at our end failed, we could not move a file your build needed, and the file was one we are responsible for moving. That is a fault at our end. Nothing in your repository, your environment variables or your project settings caused it, there is nothing there for you to change, and in most cases another attempt is already on its way without you asking for one.

This guide explains which transfers we own, the four ways one of them can fail, how we know the fault was ours rather than yours, what your build log will and will not contain, what we do about it automatically, and the one case worth bringing to us.

The Transfers We Own

A build is not only your commands. Before the first of them runs, and after the last one finishes, our platform moves bytes on your behalf. Three of those movements are ours end to end.

Your source, on the way in. We fetch an archive of your repository at the commit you pushed and unpack it inside the machine that will run the build. You never see this step succeed, which is why its failure is so easy to misread.

A toolchain, when your project needs one we do not ship. Our build image carries the common runtimes already. A few tools are fetched at build time instead, from the vendor that publishes them, because shipping every version of every tool in one image would make the image enormous and stale. Bun is the one that works this way today.

Your finished build, on the way out. When your build succeeds we package the output directory and upload it to object storage, which is where it is served from. Until that upload completes, a successful build has produced nothing anyone can reach.

Each of those is a transfer you did not ask for, cannot configure and cannot retry by hand. So when one fails, it is ours.

What Actually Happened

One of four things, and all four of them are ours.

We could not download your source. The archive never arrived. Your build had not started, none of your commands had run, and nothing of yours was read.

Your source arrived damaged. The archive downloaded but would not unpack. The dominant cause is a transfer that stopped early and left a truncated file, which is the same fault as the one above wearing different clothes. We report it separately because the two are distinguishable at our end, and because telling them apart is how we find the cause.

We could not fetch a toolchain. Your project needs a tool we fetch at build time and the fetch did not produce a usable installer, so the tool was never available to run your commands.

We could not store your finished build. This one is worth reading twice, because your build SUCCEEDED. Your code compiled, your tests passed, your output directory was produced and packaged. The upload to storage is what failed, which is the last thing that happens and the only thing between a working build and a live deployment.

Why We Can Say This One Was Ours

"It was our fault" is a claim a platform should have to earn, so here is the ground for it.

Most build failures are classified by reading text somebody else wrote: your compiler, your package manager, a registry. That reading can be wrong, and a category built on it can be argued with. This one is different. Each of the four failures above is reported by our own build guest, with a code our own code chose, about a transfer our own platform was performing. Nothing in your build output is consulted.

That matters more than it sounds, because of what this category replaced. Until recently a toolchain we failed to fetch did not surface as a fetch failure at all. The build carried on, reached the point of running the missing tool, and the shell reported that the command did not exist. You were shown a missing command, in a category that means "a program your build asked for is not there", with no retry and no suggestion that anyone but you was at fault. The failure was ours and the product spent your time pointing at your repository.

A failed upload told a similar story from the other end: a build that had genuinely succeeded was filed under a generic network error attributed to you, and left un-retried, so a working build was thrown away and the message implied you should go and look at your own connectivity.

What Your Build Log Will Show

It depends on which of the four happened, and the difference is worth knowing before you go looking.

For the two source failures and the toolchain failure, the log is very short or empty. The failure happens before or during setup, so none of your commands have printed anything yet. An empty log usually means a build that printed nothing, which sends you to inspect a build command that was working fine. Here it means the build never got far enough to print.

For the upload failure the log is COMPLETE and it is full of success. Your build ran to the end. If you read that log looking for the mistake, you will not find one, because there is not one in it. The failure is recorded in the message above the log, not inside it.

In every case the message names the transfer and, where it helps, the underlying error our tooling reported. We show you that text rather than summarising it, so you can see the same thing we see.

What We Do Automatically

We retry this failure on our own account.

All four of these failures are transient by nature. A registry or a CDN that refused or truncated one request usually answers the next one; object storage that rejected one upload usually accepts the next. So the next attempt is not a repeat of the same conditions, it is a genuinely different attempt, and that is the test we apply before spending a build on a retry.

This retry happens even when your project has automatic retries switched off. That setting governs whether you want another build spent on a failure with your name on it, which is a fair thing to ask you. A transfer we failed to complete is not that failure: you did not cause it, you cannot prevent it, and you cannot see it. So the decision is not yours to have to make, and we make it.

It is bounded at one extra attempt. A second identical failure is evidence, and evidence should reach a person rather than be eaten by a loop.

For the upload case, be aware of what that extra attempt costs: there is no way to resume a build and upload the output again, so the retry re-runs the whole build. We think that is clearly better than discarding a build that worked, but we would rather say it than let you discover it in your usage.

When to Bring It to Us

If the same deployment fails this way twice, open a ticket and quote the deployment. Two identical failures across two separate machines is no longer the transient case this category assumes, and at that point we want to look at it rather than have you keep pressing retry.

You do not need to contact us for a single occurrence that then succeeds. That is the system working as intended, and the retry that fixed it was ours to spend.

What This Category Is Not

It is not a firewall refusal. If our egress policy dropped a connection your own build made, you will see Blocked by our policy instead, which names the destination we refused and links to the allowlist. That failure is also ours, but it is a policy decision rather than a fault, and re-running it reaches the identical outcome.

It is not a network error inside your own build. If your code or your package manager could not reach something it asked for, that is a Network error, and the destination, the timing and the fix all belong to your project. We deliberately keep the two apart: folding them together would let us blame ourselves for your dependency tree, which is the same defect as blaming you for ours, pointed the other way.

It is not our sandbox dying. If the machine running your build stopped answering, you will see Our build sandbox failed, which has its own guide. Here the machine was alive and working correctly. It is reporting a failure accurately, which is the opposite state, and it is why the message you get is specific rather than a shrug.

Still need help?

Email us at support@kapsulehost.com or open a chat in KPanel.

Open KPanel