actions / actions/toolkit

@actions/artifact: BlobClient upload fails with "Bad Request" through HTTPS proxy — no proxy transport configured

Open
#2,377 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
5.9k
Forks
1.8k
PR merge metrics
No merged PRs in 30d

Description

Description

When a GitHub Actions self-hosted runner is configured with HTTPS_PROXY, the upload-artifact action fails with Error: Bad Request during the blob upload step. The @actions/artifact package creates a BlobClient from @azure/storage-blob without configuring proxy transport, causing the Azure SDK's HTTP pipeline to handle the CONNECT tunnel incorrectly.

Root cause

In packages/artifact/src/internal/upload/blob-upload.ts:

const blobClient = new BlobClient(authenticatedUploadURL)
const blockBlobClient = blobClient.getBlockBlobClient()

The BlobClient is created with only a URL — no StoragePipelineOptions with proxy configuration. The @azure/storage-blob SDK creates its own internal HTTP pipeline which may not correctly handle HTTPS CONNECT tunnels even though HTTPS_PROXY is set in the environment.

Suggested fix

Pass pipeline options with proxy configuration:

import { ProxyPolicy } from '@azure/core-rest-pipeline'

const blobClient = new BlobClient(authenticatedUploadURL, undefined, {
  proxyOptions: {
    host: process.env.HTTPS_PROXY || process.env.https_proxy,
  }
})

Or use newPipeline with the StorageSharedKeyCredential and configure the proxy in the pipeline options.

Evidence

Proxy logs confirm the CONNECT tunnel succeeds but the upload stalls:

CONNECT productionresultssa6.blob.core.windows.net:443 → status=200 (ALLOWED)
  requestSize=17259    (only ~17 KB sent)
  responseSize=8828    (error response)
  latency=74.999634s   (stalled for 75 seconds)
  user-agent: azsdk-net-Storage.Blobs/12.27.0 (.NET 8.0.25; Ubuntu 24.04.4 LTS)

Curl and Python upload 1 MB to the same blob endpoint through the same proxy in <1 second:

curl PUT 1MB to blob → HTTP 409 in 0.3s
Python PUT 1MB to blob → HTTP 409 in 0.6s

Standalone .NET HttpClient.PutAsync() also works fine (1.1s) — the issue is in how the Azure SDK BlobClient is instantiated without proxy configuration.

Workflow output

Run actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
With the provided path, there will be 1 file uploaded
Artifact name is valid!
Root directory input is valid!
Uploading artifact: trivy-scan-results--skaffold-build-24347418057-1-1776089109.zip
Beginning upload of artifact content to blob storage
Error: Bad Request

Related

  • actions/runner#4351 — same root cause in the runner's .NET ResultsHttpClient.cs which also creates BlobClient without proxy transport. The runner's step log/summary/diagnostic uploads stall in the same way.

Environment

  • Runner: GitHubActionsRunner-linux-x64/2.333.1 (self-hosted on GKE via actions-runner-controller v0.13.1)
  • Action: actions/upload-artifact@v4 (SHA bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)
  • Package: @actions/artifact v6.2.0 → @azure/storage-blob v12.30.0
  • Proxy: GCP Secure Web Proxy (HTTPS forward proxy, CONNECT tunnel, no TLS inspection)
  • Config: HTTPS_PROXY=http://<proxy-ip>:443
  • Platform: Ubuntu 24.04.4 LTS on GKE

Workaround

Add .blob.core.windows.net to NO_PROXY:

NO_PROXY=.blob.core.windows.net

This bypasses the proxy for Azure Blob traffic, but defeats the purpose of hostname-based egress control through the proxy.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/artifact/src/internal/upload/blob-upload.ts and inspect how BlobClient is constructed from authenticatedUploadURL, then review the @azure/storage-blob pipeline options used by the package. Reproduce the upload with HTTPS_PROXY configured and confirm that the artifact upload completes without the Bad Request or stall seen in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, typescript
Domain
cloud, networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
67/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.