Dokploy/dokploy · error · TRPCError

UNAUTHORIZED

UNAUTHORIZED

Error message

Please set a server to create a certificate

What it means

Thrown when creating a certificate on Dokploy Cloud (IS_CLOUD=true) without specifying a serverId. In cloud mode every certificate must be issued against a specific server, because there is no implicit 'web server' host like in self-hosted mode.

Source

Thrown at apps/dokploy/server/api/routers/certificate.ts:25

} from "@dokploy/server";
import { db } from "@dokploy/server/db";
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
import { createTRPCRouter, withPermission } from "@/server/api/trpc";
import { audit } from "@/server/api/utils/audit";
import {
	apiCreateCertificate,
	apiFindCertificate,
	apiUpdateCertificate,
	certificates,
} from "@/server/db/schema";

export const certificateRouter = createTRPCRouter({
	create: withPermission("certificate", "create")
		.input(apiCreateCertificate)
		.mutation(async ({ input, ctx }) => {
			if (IS_CLOUD && !input.serverId) {
				throw new TRPCError({
					code: "UNAUTHORIZED",
					message: "Please set a server to create a certificate",
				});
			}
			const cert = await createCertificate(
				input,
				ctx.session.activeOrganizationId,
			);
			await audit(ctx, {
				action: "create",
				resourceType: "certificate",
				resourceId: cert.certificateId,
				resourceName: cert.name,
			});
			return cert;
		}),

	one: withPermission("certificate", "read")

View on GitHub (pinned to 546686ea35)

Solutions

  1. Pass a valid `serverId` owned by your active organization in the create input
  2. If self-hosted and you see this unexpectedly, check that IS_CLOUD isn't accidentally set in the environment
  3. Make serverId required in your own client-side form/validation before calling the API

Example fix

// before
await trpc.certificate.create.mutate({ name: 'my-cert', domains: ['a.com'] });

// after
await trpc.certificate.create.mutate({ name: 'my-cert', domains: ['a.com'], serverId: 'srv_xxx' });
Defensive patterns

Strategy: validation

Validate before calling

const servers = await trpc.server.all.query();
if (!input.serverId || !servers.some(s => s.serverId === input.serverId)) {
  input.serverId = servers[0]?.serverId;
}
if (!input.serverId) throw new Error('No servers available in this organization');

Type guard

function hasServerId<T extends { serverId?: string }>(i: T): i is T & { serverId: string } {
  return typeof i.serverId === 'string' && i.serverId.length > 0;
}

Prevention

When it happens

Trigger: Calling `certificate.create` with IS_CLOUD=true and no `serverId` in the input payload.

Common situations: UI bug or custom script omitting serverId; migrating a self-hosted workflow that never needed serverId to the cloud version; schema (apiCreateCertificate) making serverId optional so it's easy to forget.

Understand the failure class

Related errors


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