danny-avila/LibreChat · error

Failed to fetch URL: ${response.status} ${response.statusTex

Error message

Failed to fetch URL: ${response.status} ${response.statusText}

What it means

Thrown by saveURLToAzure (Azure/crud.js) after fetching a remote file URL via node-fetch when response.ok is false. The fetch is gated by assertRemoteFileURL and carries timeout/size caps; this error surfaces a non-2xx status from the remote origin before any Azure upload is attempted.

Source

Thrown at api/server/services/Files/Azure/crud.js:79

 * @param {string} [params.basePath='images'] - The base folder within the container.
 * @param {string} [params.containerName] - The Azure Blob container name.
 * @returns {Promise<string>} The URL of the uploaded blob.
 */
async function saveURLToAzure({
  userId,
  URL,
  fileName,
  basePath = defaultBasePath,
  containerName,
}) {
  try {
    const maxBytes = getRemoteFileFetchMaxBytes();
    const response = await fetch(assertRemoteFileURL(URL), {
      timeout: getRemoteFileFetchTimeoutMs(),
      size: maxBytes,
    });
    if (!response.ok) {
      throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
    }
    assertRemoteFileContentLength(response.headers, maxBytes);
    const buffer = await response.buffer();
    if (buffer.length > maxBytes) {
      throw new Error(`Remote file response too large: ${buffer.length} bytes`);
    }

    return await saveBufferToAzure({ userId, buffer, fileName, basePath, containerName });
  } catch (error) {
    logger.error('[saveURLToAzure] Error uploading file from URL:', error);
    throw error;
  }
}

/**
 * Retrieves a blob URL from Azure Blob Storage.
 *
 * @param {Object} params

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Verify the URL is publicly reachable with curl -I and returns 2xx.
  2. If the origin needs auth or custom headers, fetch through a proxy that injects them rather than passing the raw URL.
  3. Handle 403/404 distinctly in the caller to give the user an accurate message.
  4. Check that the URL scheme is http/https (assertRemoteFileURL also enforces this).

Example fix

// before
const response = await fetch(assertRemoteFileURL(URL), {...});
if (!response.ok) {
  throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
}

// after
const response = await fetch(assertRemoteFileURL(URL), {...});
if (!response.ok) {
  const err = new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
  err.statusCode = response.status;
  throw err;
}
Defensive patterns

Strategy: validation

Validate before calling

// HEAD-check the URL before downloading
const head = await fetch(assertRemoteFileURL(URL), { method: 'HEAD', timeout: getRemoteFileFetchTimeoutMs() });
if (!head.ok) {
  throw new Error(`Preflight failed: ${head.status} ${head.statusText}`);
}
// proceed to GET

Try / catch

try {
  await saveURLToAzure({ userId, URL, fileName });
} catch (err) {
  const m = /^Failed to fetch URL: (\d{3})/.exec(err.message);
  if (m) {
    const status = Number(m[1]);
    return res.status(status === 404 || status === 403 ? status : 502)
      .json({ message: `Remote URL returned ${status}` });
  }
  throw err;
}

Prevention

When it happens

Trigger: POST of a remote URL to the files endpoint resolves to a non-2xx HTTP status (404, 403, 500, etc.) from the origin server, or the origin returns a redirect chain that ends in an error.

Common situations: Expired/signed S3 URL passed as an image source; origin requires auth headers not supplied; URL is behind a paywall or geo-blocked; typo in the URL; origin server is down.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/023f95e01fdc24de. Report an issue: GitHub.