@actions/artifact: BlobClient upload fails with "Bad Request" through HTTPS proxy — no proxy transport configured
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.cswhich also createsBlobClientwithout 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(SHAbbbca2ddaa5d8feaa63e36b76fdaad77386f024f) - Package:
@actions/artifactv6.2.0 →@azure/storage-blobv12.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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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