Dokploy/dokploy · error · TRPCError

UNAUTHORIZED

UNAUTHORIZED

Error message

You don't have access to this destination.

What it means

Thrown by Dokploy's volume-backup subscription endpoint when the destination's organizationId differs from the caller's active organization id. Destinations (backup storage targets) are organization-scoped, so cross-organization access is rejected with UNAUTHORIZED before any streaming begins.

Source

Thrown at apps/dokploy/server/api/routers/volume-backups.ts:302

			},
		})
		.input(
			z.object({
				backupFileName: z.string().min(1),
				destinationId: z.string().min(1),
				volumeName: z
					.string()
					.min(1)
					.regex(VOLUME_NAME_REGEX, VOLUME_NAME_MESSAGE),
				id: z.string().min(1),
				serviceType: z.enum(["application", "compose"]),
				serverId: z.string().optional(),
			}),
		)
		.subscription(async ({ input, ctx }) => {
			const destination = await findDestinationById(input.destinationId);
			if (destination.organizationId !== ctx.session.activeOrganizationId) {
				throw new TRPCError({
					code: "UNAUTHORIZED",
					message: "You don't have access to this destination.",
				});
			}
			if (input.serverId) {
				const targetServer = await findServerById(input.serverId);
				if (targetServer.organizationId !== ctx.session.activeOrganizationId) {
					throw new TRPCError({
						code: "UNAUTHORIZED",
						message: "You don't have access to this server.",
					});
				}
			}
			return observable<string>((emit) => {
				const runRestore = async () => {
					try {
						emit.next("🚀 Starting volume restore process...");
						emit.next(`📂 Backup File: ${input.backupFileName}`);

View on GitHub (pinned to 546686ea35)

Solutions

  1. Switch your active organization to the one that owns the destination
  2. Re-select the destination from the current organization's list before subscribing
  3. Verify destination.organizationId matches your session's activeOrganizationId
Defensive patterns

Strategy: validation

Validate before calling

const destination = await trpc.destination.byId.query(destinationId);
if (destination.organizationId === session.activeOrganizationId) {
 subscribeToBackupEvents(destinationId);
}

Type guard

const destinationInActiveOrg = (d: Destination, activeOrgId: string) => d.organizationId === activeOrgId;

Try / catch

catch (e) { if (e?.data?.code === 'UNAUTHORIZED' && /destination/.test(e.message)) refetchDestinations(); else throw e; }

Prevention

When it happens

Trigger: Subscribing to the volume-backup events stream with a destinationId whose owning organization differs from ctx.session.activeOrganizationId — e.g. destination id from another workspace, or the session's active org was switched.

Common situations: Client state holding a destination selected before switching organizations; deep links embedding a destinationId from a shared link; multi-org users with similarly named destinations.

Related errors


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