payloadcms/payload · error · APIError
The provided file URL is not allowed.
Error message
The provided file URL is not allowed.
What it means
Thrown as a 400 when `upload.pasteURL` is configured as an object `{ allowList }` and `isURLAllowed(input.url, allowList)` returns false — the URL's host/origin is not on the operator's approved list.
Source
Thrown at packages/plugin-mcp/src/mcp/builtin/collections/fileInput.ts:106
} else {
if (uploadConfig.pasteURL === false) {
throw new APIError(
`Uploading files from URLs is disabled for collection "${collectionSlug}".`,
400,
)
}
const url = new URL(input.url)
if (!['http:', 'https:'].includes(url.protocol)) {
throw new APIError('File URLs must use http or https.', 400)
}
if (
typeof uploadConfig.pasteURL === 'object' &&
!isURLAllowed(input.url, uploadConfig.pasteURL.allowList)
) {
throw new APIError('The provided file URL is not allowed.', 400)
}
file = await getExternalFile({
data: {
filename: sanitizeFilename(input.name || getURLFilename(url)),
url: input.url,
} as FileData,
req,
uploadConfig: {
...uploadConfig,
externalFileHeaderFilter: uploadConfig.externalFileHeaderFilter ?? (() => ({})),
},
})
file.mimetype = file.mimetype?.split(';')[0] || 'application/octet-stream'
file.size = file.data.length
}
if (maxFileSize !== undefined && Number.isFinite(maxFileSize) && file.size > maxFileSize) {View on GitHub (pinned to 00c58b35c0)
Solutions
- Add the URL's host to `upload.pasteURL.allowList` (using the same hostname format `isURLAllowed` expects)
- Re-fetch the file yourself from an allowed host and pass it as `source: 'base64'`
- Double-check the exact hostname, port, and trailing-slash against what `isURLAllowed` matches
Example fix
// before
upload: { staticURL: '/media', pasteURL: { allowList: ['cdn.example.com'] } }
// url supplied: https://assets.example.com/x.png
// after — add the missing host
upload: { staticURL: '/media', pasteURL: { allowList: ['cdn.example.com', 'assets.example.com'] } } Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the URL host against the collection's allowList
import { isURLAllowed } from 'payload/internal'
const allowed = isURLAllowed(url, uploadCfg.pasteURL && typeof uploadCfg.pasteURL === 'object' ? uploadCfg.pasteURL.allowList : undefined)
if (!allowed) throw new Error(`${url} not in pasteURL allowList`) Try / catch
import { APIError } from 'payload'
try {
await tool.call({ source: 'externalURL', url })
} catch (e) {
if (e instanceof APIError && e.statusCode === 400 && /not allowed/.test(e.message)) {
// surface to user: ask an admin to add the host, or pick a different source
}
throw e
} Prevention
- Keep the `pasteURL.allowList` in sync with the CDN domains your app actually uses
- Match exact hostnames (including subdomain and port) the way `isURLAllowed` compares them
- When adding a new external source domain, update the allowlist in the same change
When it happens
Trigger: MCP tool call with `source: 'externalURL'` whose URL host is not in `upload.pasteURL.allowList`; the allowlist uses a hostname pattern that does not match (e.g. missing `www.` or wrong port).
Common situations: Adding a new CDN/source domain without updating the allowlist; allowlist configured with exact-host entries when subdomain or wildcard matching was expected; allowlist entries with trailing slashes or ports that differ from the supplied URL.
Related errors
- Uploading files from URLs is disabled for collection "${coll
- File URLs must use http or https.
- The provided URL is not allowed.
- Redirect target is not allowed.
- Unauthorized, you must be logged in to make this request.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/1936cdbc3dbbd216.
Report an issue: GitHub.