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
Forbidden error (HTTP 403, 'You are not allowed to perform this action.') thrown at the very top of getFileFromURLHandler when req.user is falsy. The paste-URL endpoint requires an authenticated session even before collection/access checks run.
Source
Thrown at packages/payload/src/uploads/endpoints/getFileFromURL.ts:21
import { executeAccess } from '../../auth/executeAccess.js'
import { APIError } from '../../errors/APIError.js'
import { Forbidden } from '../../errors/Forbidden.js'
import { getRequestCollectionWithID } from '../../utilities/getRequestEntity.js'
import { isURLAllowed } from '../../utilities/isURLAllowed.js'
import { sanitizeFilename } from '../../utilities/sanitizeFilename.js'
import { safeFetch } from '../safeFetch.js'
// If doc id is provided, it means we are updating the doc
// /:collectionSlug/paste-url/:doc-id?src=:fileUrl
// If doc id is not provided, it means we are creating a new doc
// /:collectionSlug/paste-url?src=:fileUrl
export const getFileFromURLHandler: PayloadHandler = async (req) => {
const { id, collection } = getRequestCollectionWithID(req, { optionalID: true })
if (!req.user) {
throw new Forbidden(req.t)
}
const config = collection?.config
if (!config.upload?.pasteURL) {
throw new APIError('Pasting from URL is not enabled for this collection.', 400)
}
if (id) {
// updating doc
const accessResult = await executeAccess({ slug: config.slug, req }, config.access.update)
if (!accessResult) {
throw new Forbidden(req.t)
}
} else {
// creating doc
const accessResult = await executeAccess({ slug: config.slug, req }, config.access?.create)
if (!accessResult) {View on GitHub (pinned to 00c58b35c0)
Solutions
- Authenticate before calling: include the Payload auth token (header Payload-Auth-Token or cookie) in the request.
- On the frontend, use the Payload client's fetch with credentials: 'include' or pass the token from the auth session.
- If the endpoint should be public, write a custom access function and a wrapper — but note the user check is unconditional here, so you'd need to override the endpoint.
- Handle 403 by redirecting the user to login, then retrying.
Example fix
// before
fetch(`/api/media/paste-url?src=${encodeURIComponent(src)}`)
// after — send auth token
fetch(`/api/media/paste-url?src=${encodeURIComponent(src)}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `JWT ${token}` },
}) Defensive patterns
Strategy: validation
Validate before calling
function isAuthenticated(req: { user?: unknown }): boolean {
return Boolean(req && req.user)
}
// before calling paste-url:
if (!isAuthenticated({ user: currentUser })) redirect('/login') Type guard
const hasUser = (req: { user?: unknown }): req is { user: Record<string, unknown> } =>
Boolean(req && typeof req === 'object' && 'user' in req && req.user) Try / catch
try {
await fetch(`/api/media/paste-url?src=${encodeURIComponent(src)}`, { headers: { Authorization: `JWT ${token}` } })
} catch (e) {
if (e.status === 403) redirect('/login?next=' + encodeURIComponent(location.pathname))
} Prevention
- Send the auth token on every API call from the client SDK.
- Use credentials: 'include' for cookie-based auth cross-origin.
- Refresh expired tokens before the request.
- Hide paste-URL UI when no session is active.
When it happens
Trigger: Calling POST/GET /api/:collection/paste-url[/:doc-id]?src=<url> without a logged-in user — missing/invalid auth token, expired cookie, or no payload-auth strategy populated req.user.
Common situations: Frontend forgot to send the credentials/JWT; token expired; cookie not sent cross-origin (missing credentials: 'include'); custom auth strategy not setting req.user; testing the endpoint in a tool without auth headers.
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/42c022257b6e667d.
Report an issue: GitHub.