Skip to content

Runner egress to pkg-npm.githubusercontent.com is broken — every federated-MFE image build in the fleet fails #659

Description

@izzywdev

@claude

Raising this from FuzeFront rather than touching FuzeInfra from a consuming repo. Everything below is measured, not inferred; the fix is on your side of the boundary.

Symptom

Docker image builds on the self-hosted runner scale sets cannot download npm tarballs from pkg-npm.githubusercontent.com — the blob CDN that GitHub Packages redirects to. Every build that installs a private @izzywdev/* package hangs for 12–37 minutes and then dies.

Three observations, two repositories, two independent scale sets:

Repo Scale set Duration Error
FuzeSales fuzesales 2201.4 s npm error network
FuzeContact fuzecontact 2173.6 s npm error network
FuzeContact fuzecontact 731.1 s 403 on a blob SAS that expired at 10:03:29Z

Two independent repos on two independent scale sets converging within 28 seconds of each other is a fixed retry/timeout budget being exhausted, not variance. The 403 is the same condition caught earlier in the window — slow enough that the 5-minute pre-signed blob signature expired mid-transfer rather than slow enough to exhaust npm's own timeouts:

731.1 npm error 403 Server failed to authenticate the request. Make sure the value of
      Authorization header is formed correctly including the signature.
  - GET https://pkg-npm.githubusercontent.com/npmregistryv2prod/blobs/99821070/fuzefront-identity/1.0.0/***
        ?st=2026-08-26T09:58:19Z&se=2026-08-26T10:03:29Z&sv=2025-01-05

("Server failed to authenticate the request… including the signature" is Azure Blob's generic reply to a stale SAS, not GitHub's reply to a bad token.)

The control that isolates it

FuzeSales builds two images in the same workflow run, same commit, same runner pool, same node:20-alpine base, same npm version:

Leg Registries it fetches from Duration Result
build-push (fuzesales-api, service/Dockerfile) registry.npmjs.org only 73 s ✅ success
build-push (fuzesales, Dockerfile) + npm.pkg.github.compkg-npm.githubusercontent.com 2201 s ❌ network

service/Dockerfile copies only service/package.json and never picks up the repo-root .npmrc, so it resolves nothing from GitHub Packages. It completed a full install in 73 seconds while the leg that does hit GitHub Packages crawled for 37 minutes on the same machine.

What this rules out

  • Not the credential. npm authenticates successfully and is issued a signed download URL — a step that only happens after a valid token check.
  • Not a cross-repo package grant. The registry granted access; the failure is on the redirect target.
  • Not repo size or a missing lockfile. The 73-second control leg is in the same repo, same run.
  • Not one bad runner. Two pools, two repos, same signature.
  • Not the npm client. No npm-side tuning (--maxsockets, cache mount, retries, lockfile) fixes a transfer that cannot complete.

What to check

  1. Egress from the fuzesales and fuzecontact runner pods to pkg-npm.githubusercontent.com (443) — NetworkPolicy, egress proxy allowlist, DNS resolution, and any bandwidth shaping. This host is distinct from github.com, api.github.com, ghcr.io and npm.pkg.github.com, and an allowlist written against those four would miss it.
  2. Confirm registry.npmjs.org is unaffected (measured healthy) — the contrast is the useful signal.
  3. npm.pkg.github.com itself responds (metadata + redirect both work); only the redirect target fails.

Reproduction from inside a runner pod:

# should be fast
time curl -sS -o /dev/null -w '%{http_code} %{time_total}s\n' https://registry.npmjs.org/react

# the one that fails
time curl -sS -o /dev/null -w '%{http_code} %{time_total}s\n' https://pkg-npm.githubusercontent.com/

Impact

This is currently the top blocker on getting products to render in the FuzeFront portal. A live census against app.fuzefront.com (run 32960147607, 2026-08-26 10:49:51Z) reports 3 PASS / 10 FAIL across 13 registered apps, and only one of those passes is a genuine module-federation load. Five of the ten failures are 503s from pods whose images cannot be rebuilt — four of them (contact, fuzekeys, picker, fuzesales) are exactly the repos blocked behind this.

There are three open FuzeFront-side PRs (FuzePicker#104, FuzeContact#62, FuzeSales#73) that fix a genuine, separate credential defect in those builds. They are correct and were verified to get the builds all the way to tarball download — but none can go green until this egress problem is resolved, and no change inside those repos will change that.

Separate observation, explicitly NOT yours

On those same private repos, every ubuntu-latest (GitHub-hosted) job is refused outright — runner_id: 0, no runner assigned, no steps, dead in 2–3 s, job logs 404. That is an Actions spending-limit condition on private repos, not a cluster matter. Noting it only because anyone investigating runner health will trip over it; it needs a billing decision, not an infra change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions