Error Handling
Authentication fails. Here's what happens and how to handle it.
Invalid or expired token
Status: 401 Unauthorized
What happens: Request is rejected before reaching your handler.
@Get('protected')
@Authentication()
getProtected() {
// This never runs if token is invalid/expired
return { data: 'secret' };
}
You don't need to handle this in your code. The guard does it automatically.
On the frontend: Refresh the token and retry.
Wrong token type
When: You use @CognitoIdUser() but send an access token (or vice versa).
Status: 401 Unauthorized
// This throws if you send an access token
@Get('profile')
@Authentication()
getProfile(@CognitoIdUser() user: CognitoIdTokenPayload) {
return user;
}
Fix: Use @CognitoUser() (works with both) or send the correct token type.
Missing groups
Status: 403 Forbidden
The @Authorization decorator handles this automatically:
@Get('admin')
@Authorization(['admin'])
getAdmin() {
return { data: 'admin only' };
}
User without the 'admin' group gets a 403. No code needed.
No token
Status: 401 Unauthorized
Exception: On @PublicRoute(), request goes through with user = undefined.
@Get('welcome')
@PublicRoute()
welcome(@CognitoUser() user?: CognitoJwtPayload) {
return user ? `Hello ${user.username}` : 'Hello guest';
}
Configuration errors
When: Wrong User Pool ID, network issues fetching JWKS keys.
Status: 500 Internal Server Error
Check your config:
CognitoAuthModule.register({
jwtVerifier: {
userPoolId: 'us-east-1_XXXXX', // ← Verify this
clientId: 'your-client-id',
tokenUse: 'access',
},
})
Custom error responses
Catch all auth errors globally:
import { ExceptionFilter, Catch, ArgumentsHost, UnauthorizedException } from '@nestjs/common';
@Catch(UnauthorizedException)
export class AuthExceptionFilter implements ExceptionFilter {
catch(exception: UnauthorizedException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
response.status(401).json({
statusCode: 401,
message: 'Authentication failed',
timestamp: new Date().toISOString(),
});
}
}
Register it:
import { APP_FILTER } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_FILTER,
useClass: AuthExceptionFilter,
},
],
})
export class AppModule {}