Dokploy/dokploy · error · TRPCError
UNAUTHORIZED
UNAUTHORIZED
Error message
You need to use a server to create a compose
What it means
Thrown by `compose.create`: in Dokploy Cloud (IS_CLOUD) or when the self-hosted instance has remoteServersOnly enabled in web server settings, a compose must be attached to an explicit serverId — there is no default local server to deploy to.
Source
Thrown at apps/dokploy/server/api/routers/compose.ts:98
import { createTRPCRouter, protectedProcedure } from "../trpc";
import { audit } from "../utils/audit";
export const composeRouter = createTRPCRouter({
create: protectedProcedure
.input(apiCreateCompose)
.mutation(async ({ ctx, input }) => {
try {
const environment = await findEnvironmentById(input.environmentId);
const project = await findProjectById(environment.projectId);
await checkServiceAccess(ctx, project.projectId, "create");
const webServerSettings = await getWebServerSettings();
if (
(IS_CLOUD || webServerSettings?.remoteServersOnly) &&
!input.serverId
) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You need to use a server to create a compose",
});
}
if (project.organizationId !== ctx.session.activeOrganizationId) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You are not authorized to access this project",
});
}
if (input.serverId) {
const accessibleIds = await getAccessibleServerIds(ctx.session);
if (!accessibleIds.has(input.serverId)) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You are not authorized to access this server",
});View on GitHub (pinned to 546686ea35)
Solutions
- Pass a serverId owned by your organization in the compose create input
- If self-hosted and you want local deployment, disable remoteServersOnly in the web server settings
- Pick a default server in the UI before creating the compose
Example fix
// before
await trpc.compose.create.mutate({ name: 'api', projectId, ... });
// after
await trpc.compose.create.mutate({ name: 'api', projectId, serverId: 'srv_xxx', ... }); Defensive patterns
Strategy: validation
Validate before calling
const servers = await trpc.server.all.query();
if (!servers.length) throw new Error('Create/attach a server before adding composes');
input.serverId ??= servers[0].serverId; 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
- Require server selection in the compose form when cloud/remote-only
- Check remoteServersOnly setting before scripting compose creation
- Keep at least one healthy server per organization
When it happens
Trigger: Calling compose.create without input.serverId while IS_CLOUD=true or admin settings set remoteServersOnly.
Common situations: Custom scripts or older clients built before the remote-servers-only setting; admin enabling remoteServersOnly and existing UI flows not yet supplying a server; using the cloud version with a self-hosted-style payload.
Related errors
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/ed2a7fb6849c8dd1.
Report an issue: GitHub.