Authorization Patterns

Authorization failures are a special in-between state. Unlike validation errors that users can fix, auth errors need clear messaging and a path back to safety. Next.js 16 introduces unauthorized() and forbidden() functions that trigger dedicated pages.

In Server Components and Queries

Call unauthorized() to immediately render unauthorized.tsx:

import { unauthorized } from 'next/navigation'; export default function DashboardPage() { if (!canManagePosts()) { unauthorized(); } return <Dashboard />; }

Or in data queries that require authorization:

export const getPosts = cache(async (filter, sort) => { if (!canManagePosts()) { unauthorized(); } return await prisma.post.findMany({ ... }); });

Both throw—unauthorized() never returns.

The unauthorized.tsx Page

Create a dedicated page that matches your app's design:

import Link from 'next/link'; export default function Unauthorized() { return ( <StatusCard icon={LockKeyhole} title="Unauthorized" description="You don't have permission to access this page." > <Link href="/">Back to Blog</Link> </StatusCard> ); }

unauthorized() vs forbidden()

FunctionHTTP StatusUse When
unauthorized()401User not authenticated
forbidden()403User authenticated but lacks permission

Both render their respective .tsx files and stop execution.

October 7, 2025Updated March 1, 2026194 words