Current behavior
When using the Payload CMS image crop tool on a site deployed to Vercel, the action fails with a 500 error. The Vercel function logs show a FileRetrievalError with the message: “Blocked unsafe attempt to [URL]”.
This happens even when the URL points to our own trusted Vercel Blob Storage instance. The error originates from Payload’s generateFileData function, which performs a server-side fetch of the image to process it. This fetch is being blocked, presumably by a security layer within the Vercel serverless environment.
The only way to prevent this error is to disable the crop tool (crop: false), which is not the desired behavior.
Expected behavior
The image crop tool should function correctly. The Vercel serverless function should be able to securely fetch an image from its own associated Vercel Blob Storage URL (*.blob.vercel-storage.com) without being blocked as an “unsafe attempt”. The user should be able to crop the image and save it without any server errors.
Code, configuration, and steps that reproduce this issue
Steps to Reproduce:
- Deploy a standard Payload CMS + Next.js application to Vercel.
- Configure the
@payloadcms/storage-vercel-blobplugin to handle media uploads. - Ensure a media collection has the
croptool enabled (upload: { crop: true }). - From the Payload admin panel, upload an image.
- After the upload is complete, edit the image and attempt to use the crop tool.
- Observe the failed network request in the browser and check the Vercel function logs for the “Blocked unsafe attempt” error.
Vercel Function Log Error:
2025-08-01T18:48:31.705Z [info] ERROR: There was a problem while uploading the file. Blocked unsafe attempt to https://5qaihcvtovvt7b1s.public.blob.vercel-storage.com/Futuristic%20Art.jpg
err: {
"type": "FileRetrievalError",
"message": "There was a problem while uploading the file. Blocked unsafe attempt to https://5qaihcvtovvt7b1s.public.blob.vercel-storage.com/Futuristic%20Art.jpg",
"stack": "FileRetrievalError: ... at generateFileData ...",
"name": "FileRetrievalError"
}
src/payload.config.ts:
import { vercelBlobStorage } from '@payloadcms/storage-vercel-blob'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
// ... other imports
export default buildConfig({
// ...
db: mongooseAdapter({
url: process.env.MONGODB_URI || '',
}),
plugins: [
vercelBlobStorage({
collections: {
media: true,
},
token: process.env.BLOB_READ_WRITE_TOKEN || '',
clientUploads: true, // Using client-side uploads
}),
],
})
src/collections/Media.ts:
import type { CollectionConfig } from 'payload'
export const Media: CollectionConfig = {
slug: 'media',
upload: {
crop: true, // This is enabled, causing the issue
focalPoint: true,
imageSizes: [ /* ... */ ],
adminThumbnail: 'thumbnail',
mimeTypes: ['image/*'],
disableLocalStorage: true,
},
// ...
}
Project information
- Project URL: ambientmuse.net
- Framework: Next.js (v15.3.0) with App Router
- CMS: Payload CMS (v3.43.0)
- Environment: Vercel Production
- Storage: Vercel Blob Storage via
@payloadcms/storage-vercel-blob(v3.43.0) - Relevant Settings: Default Vercel project settings. The error occurs in standard Vercel Serverless Functions.
My question is: What is the correct, Vercel-approved way to allow a serverless function to safely fetch a resource from a trusted external URL (like its own blob storage) for processing? Is there a specific configuration for skipSafeFetch or another mechanism that is required for it to work in the Vercel environment?
Thank you for your help!