{"record":{"id":"6db14e8eeb771823","repo":"Dokploy/dokploy","slug":"unauthorized-6db14e","errorCode":"UNAUTHORIZED","errorMessage":"Please set a server to create a certificate","messagePattern":"Please set a server to create a certificate","errorType":"exception","errorClass":"TRPCError","httpStatus":401,"severity":"error","filePath":"apps/dokploy/server/api/routers/certificate.ts","lineNumber":25,"sourceCode":"} from \"@dokploy/server\";\nimport { db } from \"@dokploy/server/db\";\nimport { TRPCError } from \"@trpc/server\";\nimport { eq } from \"drizzle-orm\";\nimport { createTRPCRouter, withPermission } from \"@/server/api/trpc\";\nimport { audit } from \"@/server/api/utils/audit\";\nimport {\n\tapiCreateCertificate,\n\tapiFindCertificate,\n\tapiUpdateCertificate,\n\tcertificates,\n} from \"@/server/db/schema\";\n\nexport const certificateRouter = createTRPCRouter({\n\tcreate: withPermission(\"certificate\", \"create\")\n\t\t.input(apiCreateCertificate)\n\t\t.mutation(async ({ input, ctx }) => {\n\t\t\tif (IS_CLOUD && !input.serverId) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: \"UNAUTHORIZED\",\n\t\t\t\t\tmessage: \"Please set a server to create a certificate\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst cert = await createCertificate(\n\t\t\t\tinput,\n\t\t\t\tctx.session.activeOrganizationId,\n\t\t\t);\n\t\t\tawait audit(ctx, {\n\t\t\t\taction: \"create\",\n\t\t\t\tresourceType: \"certificate\",\n\t\t\t\tresourceId: cert.certificateId,\n\t\t\t\tresourceName: cert.name,\n\t\t\t});\n\t\t\treturn cert;\n\t\t}),\n\n\tone: withPermission(\"certificate\", \"read\")","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/Dokploy/dokploy/blob/546686ea3587f12ec5652217dedd9f7960fb6d15/apps/dokploy/server/api/routers/certificate.ts#L7-L43","documentation":"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.","triggerScenarios":"Calling `certificate.create` with IS_CLOUD=true and no `serverId` in the input payload.","commonSituations":"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.","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"],"exampleFix":"// before\nawait trpc.certificate.create.mutate({ name: 'my-cert', domains: ['a.com'] });\n\n// after\nawait trpc.certificate.create.mutate({ name: 'my-cert', domains: ['a.com'], serverId: 'srv_xxx' });","handlingStrategy":"validation","validationCode":"const servers = await trpc.server.all.query();\nif (!input.serverId || !servers.some(s => s.serverId === input.serverId)) {\n  input.serverId = servers[0]?.serverId;\n}\nif (!input.serverId) throw new Error('No servers available in this organization');","typeGuard":"function hasServerId<T extends { serverId?: string }>(i: T): i is T & { serverId: string } {\n  return typeof i.serverId === 'string' && i.serverId.length > 0;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["dokploy","trpc","certificate","cloud-only","server-required"],"backgroundTag":"cloud-required-field-missing","analyzedSha":"546686ea3587f12ec5652217dedd9f7960fb6d15","analyzedAt":"2026-08-27T05:18:58.095Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}