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 by the GCS storage adapter's `generateUploadInstructions` as a `Forbidden(req.t)` ('You are not allowed to perform this action.') when `overrideAccess` is false and either the configured `access` function returns false OR there is no `access` function and no `req.user`. It guards issuance of the signed write URL for staged uploads to Google Cloud Storage. Identical contract to the Azure adapter's check.

Source

Thrown at packages/storage-gcs/src/generateUploadInstructions.ts:32

export const generateUploadInstructions = ({
  access,
  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)
    }

    const { fileKey, sanitizedDocPrefix, sanitizedFilename } = await resolveSignedURLKey({
      collectionPrefix,
      collectionSlug,
      docPrefix,
      filename,
      req,
      useCompositePrefixes,
    })

    const [url] = await getStorageClient()
      .bucket(bucket)
      .file(fileKey)
      .getSignedUrl({
        action: 'write',
        contentType: mimeType,
        expires: Date.now() + 60 * 60 * 5,

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Ensure the request carries an authenticated user that satisfies the adapter's `access` function
  2. For trusted server-side calls, pass `overrideAccess: true`
  3. Correct the `access` predicate if the current user should be permitted
  4. For intended public uploads, configure an `access` function that returns true for that collection

Example fix

// before — anonymous server call
await payload.create({ collection: 'media', data, req: emptyReq })
// after
await payload.create({ collection: 'media', data, req: userReq, overrideAccess: true })
Defensive patterns

Strategy: validation

Validate before calling

// Server-side: pass an authenticated req or overrideAccess when generating upload instructions
await payload.create({ collection: 'media', data, req: userReq, overrideAccess: true })

Try / catch

const res = await fetch(uploadInstructionsUrl, { credentials: 'include' })
if (res.status === 403) {
  // anonymous or unauthorized — authenticate then retry
  await relogin()
}

Prevention

When it happens

Trigger: An anonymous request to generate upload instructions for a GCS-backed upload collection; a logged-in user who fails the adapter's `access({ collectionSlug, req })` check; server-side call that omits both `overrideAccess` and an authenticated request.

Common situations: Public upload form without a session; `access` predicate restricted to a role the user lacks; server-to-server upload forgetting `overrideAccess: true` or a user-bearing `req`; switching a collection from local to GCS storage without re-checking access.

Related errors


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