Skip to content

[Build] onnxruntime-node install fails: "Failed to download build list. HTTP status code = 302" (script doesn't follow redirects) #32233

Description

@is-whale

Describe the issue

onnxruntime-node postinstall script (script/install-utils.js) fails on any environment where the NuGet feed (or the proxy in front of it) returns an HTTP 3xx redirect. The script treats any non-200 status as a hard failure because it uses Node's native https.get(), which does not follow redirects.

This is a regression / gap in the install script, not a network problem on our side: curl -L downloads the same URLs successfully, and the failure is entirely deterministic from the script's redirect handling.
Root cause
script/install-utils.js has two download helpers that never handle 3xx:

async function downloadFile(url, dest) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(dest);
https
.get(url, (res) => {
if (res.statusCode !== 200) { // 302 rejected as hard error
file.close();
fs.unlinkSync(dest);
reject(new Error(Failed to download from ${url}. HTTP status code = ${res.statusCode}));
return;
}
...
async function downloadJson(url) {
return new Promise((resolve, reject) => {
https
.get(url, (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
if (!statusCode) { ... }
if (statusCode >= 400 && statusCode < 500) { resolve(null); return; }
else if (statusCode !== 200) { // 302 rejected as hard error
reject(new Error(Failed to download build list. HTTP status code = ${statusCode}));
return;
}
...
Node's built-in https.get() follows no redirects by default, so any 301/302/307/308 from the feed fails the install. This is especially visible behind HTTP proxies (which commonly rewrite/redirect), but is also reproducible without a proxy against feeds that redirect.

Suggested fix
Follow redirects in both helpers (max ~5 hops, guard against redirect loops), or use fetch() (Node 18+), which follows redirects by default:

async function downloadJson(url) {
const res = await fetch(url, { redirect: 'follow' });
if (!res.ok) {
throw new Error(Failed to download build list. HTTP status code = ${res.status});
}
const contentType = res.headers.get('content-type') || '';
if (!/^application/json/.test(contentType)) {
throw new Error(unexpected content type: ${contentType});
}
return res.json();
}

async function downloadFile(url, dest) {
const res = await fetch(url, { redirect: 'follow' });
if (!res.ok) {
throw new Error(Failed to download from ${url}. HTTP status code = ${res.status});
}
const buf = Buffer.from(await res.arrayBuffer());
fs.writeFileSync(dest, buf);
}
(Keep the existing https-based approach and add manual Location-header handling if you need to stay on older Node versions.)

Urgency

No response

Target platform

OS: Linux x64 (also reproducible on macOS arm64) Node.js: v22.23.2 npm: 10.9.8 onnxruntime-node: 1.27.0 (also affected in 1.24.x range)

Build script

npm install -g gitnexus@latest

Error / output

npm error command failed
npm error command sh -c node ./script/install
npm error /.../onnxruntime-node/script/install-utils.js:57
npm error reject(new Error(Failed to download build list. HTTP status code = ${statusCode}));
npm error Error: Failed to download build list. HTTP status code = 302

Visual Studio Version

No response

GCC / Compiler Version

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    .NETPull requests that update .net codebuildbuild issues; typically submitted using templateplatform:webissues related to ONNX Runtime web; typically submitted using template

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions