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
- Use the server-proxy path (fetchFileFromServerProxy) instead of the client fetch when CORS blocks direct reads.
- Ensure the remote host sends permissive CORS headers (Access-Control-Allow-Origin) for the admin origin.
- Validate the URL is reachable and HTTPS before fetching.
- 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
- Prefer the server proxy for URLs that may block cross-origin reads.
- Validate the URL scheme is HTTPS to avoid mixed-content blocks.
- Fall back to the server proxy automatically on client-fetch failure.
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
- Failed to initialize multipart upload
- Failed to upload part ${part} / ${partTotal}
- Failed to complete multipart upload
- Search failed
- Too many redirects.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/8c7989c800791297.
Report an issue: GitHub.