n8n-io/n8n · error · AuthError

Unauthorized

Error message

Unauthorized

What it means

Raised by the auth middleware when the presented auth cookie token is found in the invalid-auth-token repository — i.e. the token has been revoked or the user logged out. The token is checked via existsBy({ token }) before JWT verification. The resulting AuthError is caught and triggers cookie clearing and a 401 response. Distinct from an invalid/unsigned JWT (JsonWebTokenError).

Source

Thrown at packages/cli/src/auth/auth.service.ts:133

			// :projectId in req.baseUrl, so this one needs a pattern.
			new RegExp(
				`^/${escapeRegExp(restEndpoint)}/projects/[^/]+/agents/v2/:agentId/chat/attachments/:attachmentId$`,
			),
		];
	}

	createAuthMiddleware({
		allowSkipMFA,
		allowSkipPreviewAuth,
		allowUnauthenticated,
	}: CreateAuthMiddlewareOptions) {
		return async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
			const token = req.cookies[AUTH_COOKIE_NAME];

			if (token) {
				try {
					const isInvalid = await this.invalidAuthTokenRepository.existsBy({ token });
					if (isInvalid) throw new AuthError('Unauthorized');

					const [user, { usedMfa }] = await this.resolveJwt(token, req, res);
					const mfaEnforced = await this.mfaService.isMFAEnforced();

					if (mfaEnforced && !usedMfa && !allowSkipMFA) {
						// If MFA is enforced, we need to check if the user has MFA enabled and used it during authentication
						if (user.mfaEnabled) {
							// If the user has MFA enforced, but did not use it during authentication, we need to throw an error
							throw new AuthError('MFA not used during authentication');
						} else {
							// User doesn't have MFA enabled, but MFA is enforced
							// They need to set up MFA before accessing most endpoints
							if (allowUnauthenticated) {
								// Don't set req.user to avoid giving full access to semi-authenticated users
								// Instead, set a flag in authInfo to indicate MFA enrollment is required
								// This allows endpoints to handle this state appropriately (e.g., return public settings)
								req.authInfo = {
									usedMfa,

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. On the client, handle the 401 by clearing the auth cookie and redirecting to login.
  2. Ensure logout invalidates the token server-side (it does) and the client drops the cookie.
  3. If occurring app-wide after a restart/restore, have all clients re-authenticate.

Example fix

// client-side fetch wrapper
// before
const res = await fetch('/api/workflows');

// after
const res = await fetch('/api/workflows');
if (res.status === 401) {
  document.cookie = AUTH_COOKIE_NAME + '=; Max-Age=0; path=/';
  window.location.href = '/signin';
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Client: before each request, the cookie is present; nothing to pre-validate.
// Server: the check is authoritative. To reduce surface, clear cookies on logout.
await authService.invalidateToken(req); // adds token to invalid-auth-token repo

Type guard

import { AuthError } from 'n8n-workflow';
function isAuthError(e: unknown): e is AuthError {
  return e instanceof AuthError;
}

Try / catch

// Express error handler
if (err instanceof AuthError && err.message === 'Unauthorized') {
  res.clearCookie(AUTH_COOKIE_NAME);
  return res.status(401).json({ status: 'error', message: 'Unauthorized' });
}

Prevention

When it happens

Trigger: A request carries an auth cookie that was invalidated by logout, password change, admin session revocation, or token rotation. Also after a server restart where invalid tokens are persisted. The user's browser still holds the old cookie.

Common situations: User logged out in another tab but the current tab still sends the old cookie; SSO/session cleanup revoked tokens; concurrent sessions after a password change; stale cookies after an instance restore.

Understand the failure class

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/e762d061ab937d7e. Report an issue: GitHub.