{"record":{"id":"395644a4fbc4daee","repo":"payloadcms/payload","slug":"unauthorized-you-must-be-logged-in-to-make-this-r-395644","errorCode":null,"errorMessage":"Unauthorized, you must be logged in to make this request.","messagePattern":"Unauthorized, you must be logged in to make this request\\.","errorType":"http","errorClass":"UnauthorizedError","httpStatus":401,"severity":"error","filePath":"packages/plugin-mcp/src/endpoint/access.ts","lineNumber":40,"sourceCode":"  const pluginConfig = getPluginConfig({ config: req.payload.config })\n\n  if (pluginConfig.overrideGetAuthorizedMCP) {\n    return await pluginConfig.overrideGetAuthorizedMCP({\n      overrideAccess,\n      pluginConfig,\n      req,\n    })\n  }\n\n  if (req.headers) {\n    const headers = new Headers(req.headers)\n    const hasAuthorization = headers.has('Authorization')\n\n    headers.set('DisableAutologin', 'true')\n    req.user = (await req.payload.auth({ headers, req })).user\n\n    if (hasAuthorization && !req.user) {\n      throw new UnauthorizedError(req.t)\n    }\n  }\n\n  return {\n    items: await filterMCPItems({\n      items: pluginConfig.items,\n      overrideAccess,\n      req,\n    }),\n    overrideAccess,\n  }\n}\n\nexport const filterMCPItems = async ({\n  items,\n  overrideAccess,\n  req,\n}: {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/plugin-mcp/src/endpoint/access.ts#L22-L58","documentation":"The MCP access handler authenticates with the Authorization header while disabling autologin. If a credential was presented (hasAuthorization) but req.payload.auth resolved to no user, it throws UnauthorizedError — the token/API key is invalid, expired, or unrecognized.","triggerScenarios":"Expired or revoked JWT/API key; wrong auth scheme; token for a different Payload instance; API key that was rotated.","commonSituations":"Long-lived MCP client session whose token expired mid-session; API key rotated without updating clients; misconfigured auth header (e.g. basic instead of bearer).","solutions":["Refresh the token / regenerate the API key and resend the Authorization header.","Verify the auth header scheme matches the configured Payload auth strategy.","Confirm the user still exists and the credential is valid via req.payload.auth in isolation."],"exampleFix":"// before: expired token\nfetch('/mcp', { headers: { Authorization: 'JWT expired.token' } })\n// after: fresh token\nfetch('/mcp', { headers: { Authorization: `JWT ${freshToken}` } })","handlingStrategy":"validation","validationCode":"const headers = new Headers(req.headers)\nif (headers.has('Authorization')) {\n  const { user } = await req.payload.auth({ headers, req })\n  if (!user) throw new Error('Credential present but no user — refresh the token/API key')\n}","typeGuard":null,"tryCatchPattern":"try {\n  await getAuthorizedMCP({ overrideAccess, req })\n} catch (err) {\n  if (err instanceof UnauthorizedError) {\n    // refresh credential and retry, or prompt re-login\n  } else throw err\n}","preventionTips":["Refresh tokens before expiry in long-lived MCP clients.","After rotating API keys, update all clients promptly.","Use the correct auth scheme for your Payload auth strategy."],"tags":["auth","mcp","plugin-mcp","security"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}