06 / 06

What does a guard return when it needs to deny the request and how can it throw a custom exception in NestJS?

Returning false causes NestJS to throw a default ForbiddenException (403). To return a different status code or message, throw explicitly inside canActivate(). Throwing directly gives full control over the HTTP status and error message — prefer this over returning false in production guards.

Guard with explicit exception throwing
return false vs throw — when to use each:
  1. 1

    return false — NestJS throws a generic ForbiddenException(403) with no custom message.

  2. 2

    throw new UnauthorizedException() — returns 401 with a custom message.

  3. 3

    throw new ForbiddenException('Reason') — returns 403 with a descriptive reason.

  4. 4

    Always prefer explicit throws in production — clients need meaningful error messages.

  5. 5

    Custom exceptions extending HttpException are also valid inside guards.