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 S3 storage adapter's generateUploadInstructions generator. It fires when overrideAccess is falsy and either the configured access callback denies the request, or no access callback is set and req.user is absent. This gates the generation of presigned client-upload URLs.
Source
Thrown at packages/storage-s3/src/generateUploadInstructions.ts:36
export const generateUploadInstructions = ({
access,
acl,
bucket,
collectionPrefix,
getStorageClient,
useCompositePrefixes = false,
}: Args): GenerateUploadInstructions => {
return async ({
collectionSlug,
docPrefix,
filename,
filesize,
mimeType,
overrideAccess,
req,
}) => {
if (!overrideAccess && (access ? !(await access({ collectionSlug, req })) : !req.user)) {
throw new Forbidden(req.t)
}
let filesizeLimit = req.payload.config.upload.limits?.fileSize
if (filesizeLimit === Infinity) {
filesizeLimit = undefined
}
const { fileKey, sanitizedDocPrefix, sanitizedFilename } = await resolveSignedURLKey({
collectionPrefix,
collectionSlug,
docPrefix,
filename,
req,
useCompositePrefixes,
})
const signableHeaders = new Set<string>()View on GitHub (pinned to 00c58b35c0)
Solutions
- Forward the user's authentication token/cookie when the client requests upload instructions.
- For trusted server-side generation, pass overrideAccess: true in the generateUploadInstructions args.
- Provide an `access` callback to the S3 adapter matching the intended client-upload policy.
- Verify the logged-in user's role satisfies the collection's create access.
Example fix
// before
const instructions = await collection.upload({
data: { filename },
file,
// user not attached → Forbidden
})
// after — trusted server context
const instructions = await generateUploadInstructions({
collectionSlug: 'media',
filename,
overrideAccess: true,
req,
}) Defensive patterns
Strategy: validation
Validate before calling
function canRequestUploadInstructions(args: {
overrideAccess?: boolean
user?: unknown
accessResult?: boolean
}): boolean {
return Boolean(args.overrideAccess || args.user || args.accessResult)
}
if (!canRequestUploadInstructions({ overrideAccess, user: req.user })) {
throw new Error('Authentication required to request upload instructions')
} Type guard
import { Forbidden } from 'payload'
function isForbiddenError(err: unknown): err is Forbidden {
return err instanceof Forbidden
} Try / catch
try {
instructions = await generateUploadInstructions({ collectionSlug, filename, req })
} catch (err) {
if (err instanceof Forbidden) {
// prompt re-auth or surface 'no permission'
}
throw err
} Prevention
- Forward the auth token/cookie whenever the client requests upload instructions.
- Use overrideAccess: true only in trusted server contexts.
- Configure an `access` callback that mirrors the intended client-upload policy.
When it happens
Trigger: A client requests upload instructions (presigned URL) without overrideAccess, and either a custom access function returns false or there is no access function and the user is not logged in.
Common situations: Frontend directly calling generateUploadInstructions without forwarding the auth token; a server-to-server path forgot to set overrideAccess: true; access policy returns false for the user's role; expired session.
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.
- Incorrect collection
- Verification token is invalid.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/48be4a7f6bbc03f9.
Report an issue: GitHub.