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
- Switch your active organization to the one that owns the destination
- Re-select the destination from the current organization's list before subscribing
- 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
- Clear selected destination on organization switch
- Populate destination pickers from the active org only
- Validate embedded ids from links against current org before subscribing
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.