payloadcms/payload · error · NotFound
Not Found
Error message
Not Found
What it means
Reading a global where the access-control `read` policy returned `false` (and `disableErrors` is not set). Payload throws `NotFound` rather than `Forbidden` when access is denied for a global read, so the API does not leak the existence of a global the caller cannot see.
Source
Thrown at packages/payload/src/globals/operations/findOne.ts:100
}
}
// /////////////////////////////////////
// Retrieve and execute access
// /////////////////////////////////////
let accessResult!: AccessResult
if (!overrideAccess) {
accessResult = await executeAccess(
{ slug: globalConfig.slug, disableErrors, req },
globalConfig.access.read,
)
}
if (accessResult === false) {
if (!disableErrors) {
throw new NotFound(req.t)
}
return null!
}
const select = sanitizeSelect({
fields: globalConfig.flattenedFields,
select: resolveSelect({
config: globalConfig.select,
operation: 'read',
req,
select: incomingSelect,
}),
})
// /////////////////////////////////////
// Perform database operation
// /////////////////////////////////////
View on GitHub (pinned to 00c58b35c0)
Solutions
- Ensure the caller is authenticated and has read access per `globalConfig.access.read`.
- If calling server-side where access is already authorized, pass `overrideAccess: true`.
- Adjust the access function to allow the intended audience, or call with `disableErrors: true` to receive `null` instead of a throw.
Example fix
// before (unauthenticated read of restricted global)
await payload.findGlobal({ slug: 'settings', req })
// after (authenticate the user)
await payload.findGlobal({ slug: 'settings', req: authenticatedReq })
// or server-side trusted call
await payload.findGlobal({ slug: 'settings', req, overrideAccess: true }) Defensive patterns
Strategy: try-catch
Validate before calling
// before calling, gate on access yourself (server) or check auth state (client)
function canReadGlobal(user, globalAccessRead) {
if (!globalAccessRead) return true // no policy
return Boolean(globalAccessRead({ req: { user } }))
}
if (!canReadGlobal(req.user, globalConfig.access?.read)) {
// skip the call, render 'unavailable', or authenticate
} Type guard
function isNotFound(err: any): err is { name: 'NotFound'; statusCode: number } {
return err?.name === 'NotFound' || err?.statusCode === 404
} Try / catch
try {
const g = await payload.findGlobal({ slug: 'settings', req })
return g
} catch (err) {
if (err?.name === 'NotFound' || err?.statusCode === 404) {
// access denied or truly absent — treat as unavailable to the caller
return null
}
throw err
} Prevention
- Call findGlobal with `overrideAccess: true` only in trusted server contexts.
- Set `disableErrors: true` to receive `null` instead of a throw for optional reads.
- Keep `access.read` deterministic and unit-tested per role.
When it happens
Trigger: Calling `payload.findGlobal({ slug, req })` (or the REST `GET /api/globals/<slug>`) as a user whose `access.read` returns `false`; calling from an unauthenticated request on a members-only global.
Common situations: Logged-out user hitting a restricted global; role-based read access that excludes the current user; front-end fetching a global before the session is established.
Related errors
- Not Found
- The following fields are invalid: ${fieldPaths}
- You are not allowed to perform this action.
- You are not allowed to perform this action.
- You are not allowed to perform this action.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/62c4c2d701b30128.
Report an issue: GitHub.