Dokploy/dokploy · error · TRPCError

UNAUTHORIZED

UNAUTHORIZED

Error message

UNAUTHORIZED

What it means

Base tRPC middleware (protectedProcedure) that rejects any request without a valid session and user on the context. Every protected procedure runs this check, so any unauthenticated call surfaces as a bare UNAUTHORIZED error with no message.

Source

Thrown at apps/dokploy/server/api/trpc.ts:163

 * Public (unauthenticated) procedure
 *
 * This is the base piece you use to build new queries and mutations on your tRPC API. It does not
 * guarantee that a user querying is authorized, but you can still access user session data if they
 * are logged in.
 */
export const publicProcedure = t.procedure;

/**
 * Protected (authenticated) procedure
 *
 * If you want a query or mutation to ONLY be accessible to logged in users, use this. It verifies
 * the session is valid and guarantees `ctx.session.user` is not null.
 *
 * @see https://trpc.io/docs/procedures
 */
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
	if (!ctx.session || !ctx.user) {
		throw new TRPCError({ code: "UNAUTHORIZED" });
	}
	return next({
		ctx: {
			// infers the `session` as non-nullable
			session: ctx.session,
			user: ctx.user,
			// session: { ...ctx.session, user: ctx.user },
		},
	});
});

export const cliProcedure = t.procedure.use(({ ctx, next }) => {
	if (
		!ctx.session ||
		!ctx.user ||
		(ctx.user.role !== "owner" && ctx.user.role !== "admin")
	) {
		throw new TRPCError({ code: "UNAUTHORIZED" });

View on GitHub (pinned to 546686ea35)

Solutions

  1. Redirect the user to the login page when receiving UNAUTHORIZED from any tRPC call
  2. Check that the auth cookie is included (credentials/sameSite settings) in cross-origin setups
  3. Verify AUTH_SECRET / session storage env vars are stable across deployments
  4. Re-authenticate and retry the request

Example fix

// before
const res = await client.project.all.query();
// after
try { const res = await client.project.all.query(); }
catch (e) { if (e?.data?.code === 'UNAUTHORIZED') window.location.href = '/signin'; throw e; }
Defensive patterns

Strategy: try-catch

Type guard

const isTRPCUnauthorized = (e: unknown): boolean =>
  typeof e === 'object' && e !== null && (e as any)?.data?.code === 'UNAUTHORIZED' && !(e as any)?.message;

Try / catch

try { await protectedCall(); } catch (e) { if (isTRPCUnauthorized(e)) { await signOut(); redirect('/signin'); } throw e; }

Prevention

When it happens

Trigger: Calling any protectedProcedure tRPC endpoint without a valid session cookie, with an expired session, or after the session was revoked server-side.

Common situations: Session cookie expired while the app was idle; auth cookie not sent due to cross-origin misconfiguration; server restarted with a new auth secret invalidating sessions; automated scripts calling tRPC endpoints without auth headers.

Understand the failure class

Related errors


AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27). Data as JSON: /api/errors/63119b607f77366c. Report an issue: GitHub.