immich-app/immich · error · UnauthorizedException
Elevated permission is required
Error message
Elevated permission is required
What it means
An UnauthorizedException (HTTP 401) thrown by requireElevatedPermission when the session on the auth context does not have hasElevatedPermission set. Elevated permission is granted after a recent PIN/password re-authentication and is required for sensitive operations; a session that has not been elevated (or whose elevation expired) is rejected.
Source
Thrown at server/src/utils/access.ts:339
case Permission.StackDelete: {
return access.stack.checkOwnerAccess(auth.user.id, ids);
}
case Permission.WorkflowRead:
case Permission.WorkflowUpdate:
case Permission.WorkflowDelete: {
return access.workflow.checkOwnerAccess(auth.user.id, ids);
}
default: {
return new Set<string>();
}
}
};
export const requireElevatedPermission = (auth: AuthDto) => {
if (!auth.session?.hasElevatedPermission) {
throw new UnauthorizedException('Elevated permission is required');
}
};
View on GitHub (pinned to 199723261c)
Solutions
- Drive the PIN/password step-up flow to set hasElevatedPermission on the session before retrying the operation.
- Re-run the elevation flow if the elevated state has expired.
- Ensure a PIN is configured for the user if the flow requires it.
- In tests, perform the elevation request after login before calling elevated endpoints.
Example fix
// before await api.deleteSensitiveThing(id); // 401 'Elevated permission is required' // after await api.unlockWithPin(userPin); // sets hasElevatedPermission on session await api.deleteSensitiveThing(id);
Defensive patterns
Strategy: validation
Validate before calling
function hasElevated(auth) {
return Boolean(auth?.session?.hasElevatedPermission);
}
if (!hasElevated(auth)) {
await api.unlockWithPin(pin); // step-up
}
if (!hasElevated(auth)) {
return unauthorized('Elevated permission required');
} Type guard
const isElevatedPermissionError = (e: unknown): boolean => typeof e === 'object' && e !== null && (e as any).status === 401 && (e as any).message === 'Elevated permission is required';
Try / catch
try {
await api.doSensitiveOp(id);
} catch (e) {
if (isElevatedPermissionError(e)) {
await promptPinAndUnlock();
return api.doSensitiveOp(id); // retry once after step-up
}
throw e;
} Prevention
- Run the PIN/password step-up flow before any elevated endpoint.
- Track the elevated state in the client and re-elevate after timeout.
- In tests, perform elevation right after login for elevated endpoints.
When it happens
Trigger: Calling a route guarded by requireElevatedPermission without first completing the PIN/password step-up flow, or after the elevated state has timed out on the session.
Common situations: User logged in normally but the operation requires step-up auth; elevated permission expired mid-session; PIN not configured; integration tests that authenticate but skip the elevation step.
Related errors
- Not authenticated with an API Key
- Missing JWT Token
- Invalid JWT Token
- Cannot grant permissions you do not have
- Forbidden
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/703b623262734206.
Report an issue: GitHub.