ci(release): AppImage artifact upload fails with HTTP 520 during large file transfer #106

Closed
opened 2026-02-09 14:04:23 +00:00 by forbes · 1 comment
Owner

Problem

The release workflow fails when uploading the AppImage artifact (~800 MB). The .deb upload completes successfully, but the AppImage upload hits an HTTP 520 error from Cloudflare at ~93% (around 746 MB transferred), aborting the entire artifact upload step.

::error::Unexpected response. Unable to upload chunk to
https://git.kindred-systems.com/api/actions_pipeline/_apis/pipelines/workflows/160/artifacts/.../upload

Status Code: 520
Server: cloudflare
cf-ray: 9cb15488d8e3d1b1-MCI

The upload uses ~8 MB chunks. The .deb (~719 MB) finishes, but the AppImage fails partway through, suggesting a timeout or connection reset on the Cloudflare/origin side during sustained large transfers.

Artifacts involved

File Size Status
kindred-create_0~main_amd64.deb ~719 MB Uploaded
FreeCAD_main-Linux-x86_64-py311.AppImage ~800 MB Failed at ~93%
SHA256 checksums (x2) tiny Likely OK

Total attempted: ~1.53 GB, uploaded: ~1.47 GB.

Likely cause

HTTP 520 is a Cloudflare "Web server returned an unknown error" -- typically means the origin (Gitea) closed the connection or timed out. Possible factors:

  1. Cloudflare upload timeout -- sustained ~8 MB chunk uploads over several minutes may exceed Cloudflare's connection timeout for the proxied origin
  2. Gitea artifact storage limits -- the Gitea instance may have a max artifact size or total storage limit that triggers a silent failure
  3. Memory/disk pressure on the runner or Gitea host -- two large files uploading concurrently may exhaust resources

Possible fixes

  • Increase Cloudflare origin timeout if set below the upload duration (likely needs 300s+ for files this size)
  • Upload artifacts sequentially instead of concurrently to reduce sustained load
  • Add retry logic to the upload step with continue-on-error + a retry wrapper
  • Upload to an external store (e.g., MinIO/S3) and attach download URLs to the release instead of using Gitea's artifact pipeline
  • Compress the AppImage further -- currently using squashfs+zstd; check if a higher compression level meaningfully reduces size
  • Split the artifact upload into separate workflow steps so a single failure doesn't abort the entire release

Reproduction

Push any tag matching v* to trigger the release workflow. The failure occurs in the Upload Linux artifacts step.

## Problem The release workflow fails when uploading the AppImage artifact (~800 MB). The `.deb` upload completes successfully, but the AppImage upload hits an HTTP 520 error from Cloudflare at ~93% (around 746 MB transferred), aborting the entire artifact upload step. ``` ::error::Unexpected response. Unable to upload chunk to https://git.kindred-systems.com/api/actions_pipeline/_apis/pipelines/workflows/160/artifacts/.../upload Status Code: 520 Server: cloudflare cf-ray: 9cb15488d8e3d1b1-MCI ``` The upload uses ~8 MB chunks. The `.deb` (~719 MB) finishes, but the AppImage fails partway through, suggesting a timeout or connection reset on the Cloudflare/origin side during sustained large transfers. ## Artifacts involved | File | Size | Status | |------|------|--------| | `kindred-create_0~main_amd64.deb` | ~719 MB | Uploaded | | `FreeCAD_main-Linux-x86_64-py311.AppImage` | ~800 MB | **Failed at ~93%** | | SHA256 checksums (x2) | tiny | Likely OK | Total attempted: ~1.53 GB, uploaded: ~1.47 GB. ## Likely cause HTTP 520 is a Cloudflare "Web server returned an unknown error" -- typically means the origin (Gitea) closed the connection or timed out. Possible factors: 1. **Cloudflare upload timeout** -- sustained ~8 MB chunk uploads over several minutes may exceed Cloudflare's connection timeout for the proxied origin 2. **Gitea artifact storage limits** -- the Gitea instance may have a max artifact size or total storage limit that triggers a silent failure 3. **Memory/disk pressure on the runner or Gitea host** -- two large files uploading concurrently may exhaust resources ## Possible fixes - **Increase Cloudflare origin timeout** if set below the upload duration (likely needs 300s+ for files this size) - **Upload artifacts sequentially** instead of concurrently to reduce sustained load - **Add retry logic** to the upload step with `continue-on-error` + a retry wrapper - **Upload to an external store** (e.g., MinIO/S3) and attach download URLs to the release instead of using Gitea's artifact pipeline - **Compress the AppImage further** -- currently using squashfs+zstd; check if a higher compression level meaningfully reduces size - **Split the artifact upload** into separate workflow steps so a single failure doesn't abort the entire release ## Reproduction Push any tag matching `v*` to trigger the release workflow. The failure occurs in the `Upload Linux artifacts` step.
forbes added the bugci/cd labels 2026-02-09 14:04:23 +00:00
Author
Owner

Fixed by adding a host-level /etc/hosts override on the runner machine:

10.0.100.231 git.kindred-systems.com

Added via /etc/cloud/templates/hosts.debian.tmpl (cloud-init managed). This routes all Gitea traffic from the runner through the internal network, bypassing Cloudflare entirely. No CI workflow changes needed.

The artifact upload was failing because the runner was routing ~800 MB uploads through Cloudflare's proxy, which timed out (HTTP 520) on sustained large transfers.

Fixed by adding a host-level `/etc/hosts` override on the runner machine: ``` 10.0.100.231 git.kindred-systems.com ``` Added via `/etc/cloud/templates/hosts.debian.tmpl` (cloud-init managed). This routes all Gitea traffic from the runner through the internal network, bypassing Cloudflare entirely. No CI workflow changes needed. The artifact upload was failing because the runner was routing ~800 MB uploads through Cloudflare's proxy, which timed out (HTTP 520) on sustained large transfers.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#106