payloadcms/payload · error · Forbidden

You are not allowed to perform this action.

Error message

You are not allowed to perform this action.

What it means

Thrown as Forbidden (HTTP 403) by the Vercel Blob storage adapter when generating client upload instructions. Identical gate to the S3 adapter: overrideAccess falsy AND (clientUploadsAccess denies, or no clientUploadsAccess and req.user is null).

Source

Thrown at packages/storage-vercel-blob/src/adapter.ts:58

    uploadInstructions: {
      adminHandler: {
        path: '@payloadcms/storage-vercel-blob/client#VercelBlobClientUploadHandler',
      },
      enabled: Boolean(clientUploads),
      generate: async ({
        collectionSlug,
        docPrefix,
        filename,
        filesize,
        mimeType,
        overrideAccess,
        req,
      }) => {
        if (
          !overrideAccess &&
          (clientUploadsAccess ? !(await clientUploadsAccess({ collectionSlug, req })) : !req.user)
        ) {
          throw new Forbidden(req.t)
        }

        const resolved = await resolveSignedURLKey({
          collectionPrefix: prefix,
          collectionSlug,
          docPrefix,
          filename,
          req,
          useCompositePrefixes,
        })

        return {
          name: 'uploadToVercelBlob',
          type: 'dispatch',
          data: {
            pathname: resolved.fileKey,
            token: await generateClientTokenFromReadWriteToken({
              addRandomSuffix,

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Authenticate the request before generating Vercel Blob upload instructions.
  2. Pass overrideAccess: true for trusted server-side generation.
  3. Configure a clientUploadsAccess callback that matches the intended public/auth policy.
  4. Ensure the auth token/cookie reaches the adapter invocation.

Example fix

// before
const adapter = new VercelBlobAdapter({ token, collectionSlugs: ['media'] })
// unauthenticated client → Forbidden

// after
const adapter = new VercelBlobAdapter({
  token,
  collectionSlugs: ['media'],
  clientUploadsAccess: async ({ req }) => Boolean(req.user),
})
// and on the server call:
// generateUploadInstructions({ overrideAccess: true, req, ... })
Defensive patterns

Strategy: validation

Validate before calling

function canRequestVercelBlobInstructions(args: {
  overrideAccess?: boolean
  user?: unknown
  clientUploadsAccessResult?: boolean
}): boolean {
  return Boolean(args.overrideAccess || args.user || args.clientUploadsAccessResult)
}

if (!canRequestVercelBlobInstructions({ overrideAccess, user: req.user })) {
  throw new Error('Authentication required to request Vercel Blob upload instructions')
}

Type guard

import { Forbidden } from 'payload'

function isForbidden(err: unknown): err is Forbidden {
  return err instanceof Forbidden
}

Try / catch

try {
  await generateUploadInstructions({ collectionSlug, filename, req })
} catch (err) {
  if (err instanceof Forbidden) {
    redirectToLogin()
    return
  }
  throw err
}

Prevention

When it happens

Trigger: Client requests Vercel Blob upload instructions without overrideAccess while unauthenticated, or while a configured clientUploadsAccess callback returns false.

Common situations: Unauthenticated frontend calling the upload-instructions endpoint; custom clientUploadsAccess callback that rejects valid users; server path missing overrideAccess; session expired between page load and upload start.

Related errors


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