immich-app/immich · warning
Denied access to admin only route
Error message
Denied access to admin only route: ${uri} What it means
During request authentication (validate + authorize), if the resolved user is not an admin but the route is flagged adminRoute, access is denied: this warning is logged with the URI and a ForbiddenException('Forbidden') is thrown. This is the server enforcing role-based access on admin-only endpoints.
Solutions
- Use an administrator account or an admin's API key for admin-only endpoints.
- If the user should be admin, promote them in the admin Users page.
- For automations, find a non-admin endpoint or scope the integration appropriately.
- Confirm the request isn't accidentally routed to an admin endpoint due to a wrong URL.
Defensive patterns
Strategy: validation
Validate before calling
// client-side guard before calling an admin API
const user = await api.getMyUser();
if (!user.isAdmin) throw new Error('Admin privileges required for this endpoint'); Type guard
const isAdminUser = (u: { isAdmin: boolean }): u is { isAdmin: true } => u.isAdmin === true; Try / catch
try {
await api.adminEndpoint();
} catch (e) {
if (e instanceof ForbiddenException) {
showToast('This action requires an administrator account');
} else throw e;
} Prevention
- Only call admin-flagged endpoints with an admin account or admin API key.
- Check /api/users/me isAdmin before attempting admin operations in scripts.
- Promote users via the admin Users page when they genuinely need access.
- Never reuse a normal user's key for admin automation.
When it happens
Trigger: Any API call to a route whose metadata marks adminRoute=true while the authenticated user's isAdmin is false.
Common situations: A non-admin user hitting admin endpoints (user management, server settings, jobs) directly via API; custom scripts/integrations using an admin-only endpoint with a normal user's API key.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Denied access to non-shared route
- Attempted to clear cache, but rmtree is not safe on this…
- Elevated permission is required
- Failed login attempt for user
- Forbidden
AI-assisted analysis of immich-app/immich@f48d4b3321 (2026-09-15).
Data as JSON: /api/errors/7506195d9d9f56db.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/auth.service.ts:221
async adminSignUp(dto: SignUpDto): Promise<UserAdminResponseDto> {
const admin = await this.createUser({
isAdmin: true,
email: dto.email,
name: dto.name,
password: dto.password,
storageLabel: 'admin',
});
return mapUserAdmin(admin);
}
async authenticate({ headers, queryParams, metadata }: ValidateRequest): Promise<AuthDto> {
const authDto = await this.validate({ headers, queryParams });
const { adminRoute, sharedLinkRoute, uri } = metadata;
const requestedPermission = metadata.permission ?? Permission.All;
if (!authDto.user.isAdmin && adminRoute) {
this.logger.warn(`Denied access to admin only route: ${uri}`);
throw new ForbiddenException('Forbidden');
}
if (authDto.sharedLink && !sharedLinkRoute) {
this.logger.warn(`Denied access to non-shared route: ${uri}`);
throw new ForbiddenException('Forbidden');
}
if (
authDto.apiKey &&
requestedPermission !== false &&
!isGranted({ requested: [requestedPermission], current: authDto.apiKey.permissions })
) {
throw new ForbiddenException(`Missing required permission: ${requestedPermission}`);
}
return authDto;
}View on GitHub (pinned to f48d4b3321)