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 a Forbidden error (HTTP 403) from the R2 multipart-upload handler after the access callback returns false. The access callback defaults to defaultR2ClientUploadsAccess, which delegates to the collection's config.access.create policy, falling back to a logged-in user check.
Source
Thrown at packages/storage-r2/src/handleMultiPartUpload.ts:50
export const getHandleMultiPartUpload =
({
access = defaultR2ClientUploadsAccess,
bucket,
collections,
useCompositePrefixes = false,
}: Args): PayloadHandler =>
async (req) => {
const params = Object.fromEntries(req.searchParams) as R2StorageMultipartUploadHandlerParams
const collectionSlug = params.collection
const filetype = params.fileType
const collectionConfig = collections[collectionSlug]
if (!collectionConfig) {
throw new APIError(`Collection ${collectionSlug} was not found in R2 Storage options`)
}
if (!(await access({ collectionSlug, req }))) {
throw new Forbidden(req.t)
}
const collectionPrefix = (typeof collectionConfig === 'object' && collectionConfig.prefix) || ''
const { fileKey, sanitizedFilename } = await resolveSignedURLKey({
collectionPrefix,
collectionSlug,
docPrefix: params.docPrefix ?? undefined,
filename: params.fileName,
req,
useCompositePrefixes,
})
const multipartId = params.multipartId
const multipartKey = params.multipartKey
const multipartNumber = parseInt(params.multipartNumber || '')
if (multipartId && multipartKey) {
const multipartUpload = bucket.resumeMultipartUpload(multipartKey, multipartId)View on GitHub (pinned to 00c58b35c0)
Solutions
- Ensure the requester is authenticated (session cookie / token present) before initiating the multipart upload.
- Review the collection's config.access.create policy and confirm it permits the user's role.
- If public uploads are intended, set an access function on the R2 adapter that returns true for the relevant collection.
- Pass a custom `access` callback to the R2 adapter that reflects the intended policy instead of the default.
Example fix
// before — default access requires a logged-in user
const r2Adapter = new R2Storage({ bucket, collections: { media: {} } })
// after — allow public uploads to 'media' only
const r2Adapter = new R2Storage({
bucket,
collections: { media: {} },
access: async ({ collectionSlug, req }) =>
collectionSlug === 'media' ? true : Boolean(req.user),
}) Defensive patterns
Strategy: try-catch
Validate before calling
// Before initiating, ensure the user is authenticated
if (!user) {
throw new Error('Sign in required to upload files.')
}
// Optionally call the collection's create access locally if accessible
Type guard
import { Forbidden } from 'payload'
function isForbidden(err: unknown): err is Forbidden {
return err instanceof Forbidden
} Try / catch
try {
await initiateMultipartUpload({ collection: slug })
} catch (err) {
if (err instanceof Forbidden) {
// redirect to login or show 'permission denied'
redirectToLogin()
return
}
throw err
} Prevention
- Verify the user session is valid before showing the upload UI.
- Mirror the collection's create-access policy in the client to disable the upload control preemptively.
- Provide a custom access callback with clear, debuggable logic rather than relying on the default.
When it happens
Trigger: An authenticated (or anonymous) user initiates a multipart upload and the access function resolves to false: either config.access.create returned false, or no access function and req.user is null, or a custom access function denied the request.
Common situations: Public/unauthenticated upload attempt on a collection whose create access requires a user; a logged-in user whose role lacks create permission; a custom access function with a bug that returns falsy for valid users; access policy depends on req.user data that is missing.
Related errors
- You are not allowed to perform this action.
- You are not allowed to perform this action.
- You are not allowed to perform this action.
- Collection ${collectionSlug} not found
- Incorrect collection
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/c844ff3d5ac14213.
Report an issue: GitHub.