can1357/oh-my-pi · error · ArchiveError

Remote archive request failed (HTTP ${probe.status})

Error message

Remote archive request failed (HTTP ${probe.status})

What it means

httpByteSource() probes the remote archive with a Range request and expects either 200 (no range support, full-body fallback) or 206 (range support). Any other status — 403, 404, 500, 416, redirects handled as errors, etc. — is rejected with this ArchiveError and the response body is cancelled. It is the generic 'the HTTP probe did not succeed' guard at the start of remote archive access.

Source

Thrown at packages/utils/src/ar/source.ts:108

	const probe = await doFetch(url, { headers });
	if (probe.status === 200) {
		// No range support: buffer the whole body once, bounded.
		const cap = options.maxFallbackBytes ?? HTTP_FALLBACK_CAP;
		const declared = Number(probe.headers.get("content-length") ?? 0);
		if (declared > cap) {
			throw new ArchiveError(
				`Remote archive is too large to buffer without range support (${declared} > ${cap} bytes)`,
			);
		}
		const bytes = new Uint8Array(await probe.arrayBuffer());
		if (bytes.byteLength > cap) {
			throw new ArchiveError(`Remote archive is too large to buffer without range support (> ${cap} bytes)`);
		}
		return memoryByteSource(bytes);
	}
	if (probe.status !== 206) {
		await probe.body?.cancel();
		throw new ArchiveError(`Remote archive request failed (HTTP ${probe.status})`);
	}
	await probe.body?.cancel();
	// `Content-Range: bytes 0-0/12345` carries the total size.
	const contentRange = probe.headers.get("content-range");
	const total = contentRange ? Number(/\/(\d+)$/.exec(contentRange)?.[1]) : Number.NaN;
	if (!Number.isSafeInteger(total) || total < 0) {
		throw new ArchiveError("Remote archive did not report a valid size in Content-Range");
	}
	return {
		size: total,
		async read(start, end) {
			assertValidRange(start, end);
			if (start === end) return new Uint8Array(0);
			const response = await doFetch(url, {
				headers: { ...options.headers, range: `bytes=${start}-${end - 1}` },
			});
			if (response.status !== 206) {
				await response.body?.cancel();

View on GitHub (pinned to 9690622007)

Solutions

  1. Log/inspect the HTTP status in the message and fix the URL or credentials accordingly (401/403 → auth, 404 → path, 5xx → server)
  2. Pass authorization headers via httpByteSource(url, { headers: { authorization: 'Bearer ...' } }) if the archive requires auth
  3. Refresh or regenerate presigned/expired URLs immediately before calling httpByteSource
  4. Retry with backoff for transient 5xx/429 statuses; fail fast on 4xx

Example fix

// before: bare URL fails with 403 on a private bucket
const src = await httpByteSource("https://s3.example/private.tar");
// after: supply auth headers
const src = await httpByteSource("https://s3.example/private.tar", {
	headers: { authorization: `Bearer ${token}` },
});
Defensive patterns

Strategy: retry

Validate before calling

const probe = await fetch(url, { method: "HEAD", headers });
if (!probe.ok) throw new Error(`archive URL unreachable: HTTP ${probe.status}`);

Try / catch

try {
	const src = await httpByteSource(url, { headers });
} catch (err) {
	if (err instanceof ArchiveError && /HTTP \d+/.test(err.message)) {
		const status = Number(/HTTP (\d+)/.exec(err.message)?.[1]);
		if (status === 429 || status >= 500) return retryWithBackoff();
		if (status === 401 || status === 403) return refreshCredentialsAndRetry();
		throw new Error(`archive unavailable (HTTP ${status}); check URL and auth`, { cause: err });
	}
	throw err;
}

Prevention

When it happens

Trigger: Calling httpByteSource(url) where the probe request returns a status other than 200 or 206: expired/missing auth (401/403), wrong URL (404), server error (5xx), presigned URL expiration, or a 416 from a server that mis-handles the Range header.

Common situations: Stale or revoked S3 presigned URLs (403); archives moved or deleted after a manifest was generated (404); corporate proxies blocking the host (407/502); rate limiting (429); pointing at an API endpoint instead of the raw file.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f75bbbc83b9c03fe. Report an issue: GitHub.