payloadcms/payload · error

Fetch failed with status: ${response.status}

Error message

Fetch failed with status: ${response.status}

What it means

A plain Error thrown in useUploadFromUrl's fetchFileFromClient when a direct browser fetch of the user-pasted URL returns non-ok. This is the client-side branch (the alternative to the server proxy) for the 'upload from URL' feature.

Source

Thrown at packages/ui/src/elements/Upload/useUploadFromUrl.ts:89

        return false
      }

      const fileName = getFileNameFromUrl({ overrideFileName: uploadControlFileName, url })
      onFileFetched(new File([blob], fileName, { type: blob.type }))
      setUploadStatus('idle')
      closeModal(pasteURLDrawerSlug)
      setFileUrl('')
      return true
    },
    [closeModal, onFileFetched, setUploadStatus, t, uploadConfig, uploadControlFileName],
  )

  const fetchFileFromClient = useCallback(
    async (url: string): Promise<boolean> => {
      const response = await fetch(url)

      if (!response.ok) {
        throw new Error(`Fetch failed with status: ${response.status}`)
      }

      const blob = await response.blob()
      return acceptFetchedBlob({ blob, url })
    },
    [acceptFetchedBlob],
  )

  const fetchFileFromServerProxy = useCallback(
    async (url: string): Promise<boolean> => {
      const pasteURL: `/${string}` = `/${collectionSlug}/paste-url${id ? `/${id}?` : '?'}src=${encodeURIComponent(url)}`
      const response = await fetch(formatAdminURL({ apiRoute: api, path: pasteURL }))

      if (!response.ok) {
        throw new Error(`Fetch failed with status: ${response.status}`)
      }

      const blob = await response.blob()

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Use the server-proxy path (fetchFileFromServerProxy) instead of the client fetch when CORS blocks direct reads.
  2. Ensure the remote host sends permissive CORS headers (Access-Control-Allow-Origin) for the admin origin.
  3. Validate the URL is reachable and HTTPS before fetching.
  4. Catch the error and fall back to the server proxy automatically.

Example fix

// before
const fetchFileFromClient = useCallback(async (url: string) => {
  const response = await fetch(url)
  if (!response.ok) throw new Error(`Fetch failed with status: ${response.status}`)
  const blob = await response.blob()
  return acceptFetchedBlob({ blob, url })
}, [acceptFetchedBlob])

// after — fall back to server proxy on client failure
const fetchFileFromClient = useCallback(async (url: string) => {
  try {
    const response = await fetch(url)
    if (!response.ok) throw new Error(`Fetch failed with status: ${response.status}`)
    const blob = await response.blob()
    return acceptFetchedBlob({ blob, url })
  } catch {
    return fetchFileFromServerProxy(url)
  }
}, [acceptFetchedBlob, fetchFileFromServerProxy])
Defensive patterns

Strategy: fallback

Validate before calling

async function isDirectlyFetchable(url: string): Promise<boolean> {
  try {
    const res = await fetch(url, { method: 'HEAD' })
    return res.ok
  } catch {
    return false
  }
}

if (!(await isDirectlyFetchable(url))) {
  return fetchFileFromServerProxy(url)
}

Type guard

function isClientFetchFailure(err: unknown): err is Error {
  return err instanceof Error && /Fetch failed with status/i.test(err.message)
}

Try / catch

try {
  return await fetchFileFromClient(url)
} catch (err) {
  if (isClientFetchFailure(err)) {
    return fetchFileFromServerProxy(url) // CORS-safe fallback
  }
  throw err
}

Prevention

When it happens

Trigger: The user pastes a URL; the browser fetches it directly and the remote returns non-2xx (404, 403) or the fetch is blocked by CORS so response.ok is false / the fetch rejects.

Common situations: CORS policy on the remote host blocks cross-origin reads from the admin domain; the URL is wrong/expired (404); the remote requires auth/Referer the browser can't supply; mixed-content (https admin fetching http URL).

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/8c7989c800791297. Report an issue: GitHub.