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
- Pass a valid `serverId` owned by your active organization in the create input
- If self-hosted and you see this unexpectedly, check that IS_CLOUD isn't accidentally set in the environment
- 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
- Make serverId a required UI field on cloud deployments
- Default the form to the first accessible server
- Add client-side zod .min(1) on serverId when running cloud builds
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/6db14e8eeb771823.
Report an issue: GitHub.