cube-js/cube · error · Error

unexpected response ${response.statusText}

Error message

unexpected response ${response.statusText}

What it means

downloadAndExtractFile() fetches a remote file and throws this error whenever the HTTP response is not ok (response.ok is false, i.e. status outside 2xx). The response's statusText is embedded in the message so the developer can see the HTTP-level reason for the failed download.

Source

Thrown at packages/cubejs-backend-shared/src/http-utils.ts:192

type DownloadAndExtractFile = {
  showProgress: boolean;
  cwd: string;
  skipExtract?: boolean;
  dstFileName?: string;
};

export async function downloadAndExtractFile(url: string, { cwd, skipExtract, dstFileName }: DownloadAndExtractFile) {
  const request = new Request(url, {
    headers: new Headers({
      'Content-Type': 'application/octet-stream',
    }),
    agent: await getHttpAgentForProxySettings(),
  });

  const response = await fetch(request);
  if (!response.ok) {
    throw new Error(`unexpected response ${response.statusText}`);
  }

  const bar = new SingleBar({
    format: 'Downloading [{bar}] {percentage}% | Speed: {speed}',
  });
  bar.start(100, 0);

  try {
    mkdirpSync(cwd);
  } catch (e: any) {
    internalExceptions(e);
  }

  const savedFilePath = await streamWithProgress(response, ({ progress, speed, eta }) => {
    bar.update(progress, {
      speed,
      eta,
    });

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Check the message's statusText/status: fix the URL or version so the resource actually exists (404) or is accessible (403)
  2. Verify network/proxy settings — set HTTPS_PROXY/http_proxy env vars so fetch can reach the host through the corporate proxy
  3. If downloading a JDBC driver manually, place the jar in the expected .cubejs-system-cubes directory to skip the download
  4. Retry later if the status indicates a transient server-side failure (5xx)

Example fix

// before (404 - wrong version)
await downloadJDBCDriver('nonexistent-dialect');
// after
await downloadJDBCDriver('postgres'); // ensure the driver/version exists in the release repo
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(url, { method: 'HEAD' });
if (!res.ok) throw new Error(`Download URL unavailable: ${res.status} ${res.statusText} for ${url}`);

Type guard

null

Try / catch

try {
  await downloadAndExtractFile(url, { cwd, showProgress: true });
} catch (e) {
  if (e.message.startsWith('unexpected response')) {
    const status = e.message.replace('unexpected response ', '');
    console.error(`Download failed (HTTP ${status}); verify the URL/version and proxy settings`);
  } else throw e;
}

Prevention

When it happens

Trigger: Any call to downloadAndExtractFile (used by getExternalMaven, downloadJDBCDriver, downloadBinaryFromRelease) where the remote server returns 404, 403, 500, etc. — e.g. a bad release/version URL, missing artifact, private repo requiring auth, or rate-limited/forbidden CDN response.

Common situations: Specifying a JDBC driver or Cube Store version that does not exist in the release repo; corporate proxy blocking the download (403/407); GitHub/release URL changed or artifact renamed; offline/blocked network producing gateway errors.

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 cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/abc7f38d05fe59d2. Report an issue: GitHub.