payloadcms/payload · error · APIError

Uploading files from URLs is disabled for collection "${coll

Error message

Uploading files from URLs is disabled for collection "${collectionSlug}".

What it means

Thrown as a 400 when the caller uses `source: 'externalURL'` but the collection's upload config explicitly disables URL pasting via `pasteURL: false`. It is a deliberate guard — the operator has opted out of remote-URL ingestion for this collection.

Source

Thrown at packages/plugin-mcp/src/mcp/builtin/collections/fileInput.ts:90

  if (!uploadConfig) {
    throw new APIError(`Collection "${collectionSlug}" does not support file uploads.`, 400)
  }

  const maxFileSize = req.payload.config.upload.limits?.fileSize
  let file: File

  if (input.source === 'base64') {
    const data = decodeBase64({ maxFileSize, value: input.data })

    file = {
      name: sanitizeFilename(input.name),
      data,
      mimetype: input.mimeType,
      size: data.length,
    }
  } 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)
    }

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Switch the tool call to `source: 'base64'` (download the URL server-side yourself, then pass the bytes)
  2. If remote-URL ingestion is intended for this collection, set `upload.pasteURL` to `true` or to an `{ allowList }` object
  3. Use `source: 'uploadReference'` after a normal staged upload

Example fix

// before — collection has pasteURL disabled
upload: { staticURL: '/media', pasteURL: false }
// after — re-enable with an allowlist
upload: { staticURL: '/media', pasteURL: { allowList: ['https://cdn.example.com'] } }
Defensive patterns

Strategy: validation

Validate before calling

// Check the collection's pasteURL setting before using externalURL
const cfg = payload.config.collections.find(c => c.slug === slug)?.upload
if (cfg?.pasteURL === false) throw new Error(`${slug} has pasteURL disabled — use base64`)

Try / catch

import { APIError } from 'payload'
try {
  await tool.call({ source: 'externalURL', url })
} catch (e) {
  if (e instanceof APIError && e.statusCode === 400 && /Uploading files from URLs is disabled/.test(e.message)) {
    // fall back to fetching then base64
    const buf = Buffer.from(await (await fetch(url)).arrayBuffer())
    return tool.call({ source: 'base64', name, mimeType, data: buf.toString('base64') })
  }
  throw e
}

Prevention

When it happens

Trigger: An MCP upload tool call with `source: 'externalURL'` against a collection whose `upload.pasteURL === false`; an environment where paste-from-URL was turned off for security but a client still tries the externalURL source.

Common situations: Compliance/security hardening that disabled `pasteURL`; copying a tool invocation that worked on a different (pasteURL-enabled) collection; misreading `pasteURL: false` as the default.

Related errors


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