{"record":{"id":"193fe834b8420088","repo":"n8n-io/n8n","slug":"401-193fe8","errorCode":"401","errorMessage":"Unauthenticated","messagePattern":"Unauthenticated","errorType":"exception","errorClass":"UnauthenticatedError","httpStatus":401,"severity":"warning","filePath":"packages/cli/src/controller.registry.ts","lineNumber":238,"sourceCode":"\t\t\tmiddlewares.push(...route.middlewares);\n\t\t}\n\n\t\treturn middlewares;\n\t}\n\n\tprivate createLicenseMiddleware(feature: BooleanLicenseFeature): RequestHandler {\n\t\treturn (_req, res, next) => {\n\t\t\tif (!this.license.isLicensed(feature)) {\n\t\t\t\tres.status(403).json({ status: 'error', message: 'Plan lacks license for this feature' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnext();\n\t\t};\n\t}\n\n\tprivate createScopedMiddleware(accessScope: AccessScope): RequestHandler {\n\t\treturn async (req, res, next) => {\n\t\t\tif (!isAuthenticatedRequest(req)) throw new UnauthenticatedError();\n\t\t\tif (!req.user) throw new UnauthenticatedError();\n\n\t\t\tconst { scope, globalOnly } = accessScope;\n\n\t\t\ttry {\n\t\t\t\tif (!(await userHasScopes(req.user, [scope], globalOnly, req.params))) {\n\t\t\t\t\tres.status(403).json({\n\t\t\t\t\t\tstatus: 'error',\n\t\t\t\t\t\tmessage: RESPONSE_ERROR_MESSAGES.MISSING_SCOPE,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof NotFoundError) {\n\t\t\t\t\tres.status(404).json({ status: 'error', message: error.message });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthrow error;","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controller.registry.ts#L220-L256","documentation":"Thrown as `UnauthenticatedError` (HTTP 401) by `createScopedMiddleware` when `isAuthenticatedRequest(req)` returns false — i.e. the request lacks a valid auth cookie/API key/JWT. This fires before any scope check, for any route that declares an `@Scope`/accessScope. The error is caught by the global error handler and returned as a 401 response.","triggerScenarios":"Calling a scoped REST endpoint with no credentials, an expired session cookie, a revoked API key, or a malformed Authorization header.","commonSituations":"Session timed out in the browser; API client forgot to send the API key; cookie not sent cross-origin due to SameSite rules; reverse proxy stripping the auth header.","solutions":["Include a valid `Authorization: Bearer <api-key>` header or a valid session cookie.","Re-authenticate to obtain a fresh session if the cookie expired.","Check that your reverse proxy forwards the `Authorization`/`Cookie` headers.","For browser clients, confirm `SameSite`/`Secure` cookie attributes match your deployment."],"exampleFix":"// before\nfetch('/rest/v1/users', {})  // 401\n// after\nfetch('/rest/v1/users', { headers: { Authorization: `Bearer ${apiKey}` } })","handlingStrategy":"validation","validationCode":"function authHeader(cookie?: string, apiKey?: string) {\n  if (apiKey) return { Authorization: `Bearer ${apiKey}` };\n  if (cookie) return { Cookie: cookie };\n  throw new Error('No credentials: provide an API key or session cookie.');\n}","typeGuard":"function isAuthenticated(res: Response): boolean { return res.status !== 401; }","tryCatchPattern":"try { await api.get('/users'); } catch (e) { if (e.response?.status === 401) { await reauthenticate(); await retry(); } else throw e; }","preventionTips":["Centralize auth header injection in a single client wrapper.","Handle session expiry centrally and refresh transparently."],"tags":["api","auth","rest","unauthenticated","user-error"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}