{"record":{"id":"ac31c492355576eb","repo":"RocketChat/Rocket.Chat","slug":"error-not-authorized","errorCode":"error-not-authorized","errorMessage":"error-not-authorized","messagePattern":"error-not-authorized","errorType":"error_code","errorClass":null,"httpStatus":400,"severity":"error","filePath":"apps/meteor/ee/server/api/ldap.ts","lineNumber":36,"sourceCode":"API.v1.post(\n\t'ldap.syncNow',\n\t{\n\t\tauthRequired: true,\n\t\tforceTwoFactorAuthenticationForNonEnterprise: true,\n\t\ttwoFactorRequired: true,\n\t\tresponse: {\n\t\t\t200: ldapSyncNowResponseSchema,\n\t\t\t400: validateBadRequestErrorResponse,\n\t\t\t401: validateUnauthorizedErrorResponse,\n\t\t},\n\t},\n\tasync function action() {\n\t\tif (!this.userId) {\n\t\t\tthrow new Error('error-invalid-user');\n\t\t}\n\n\t\tif (!(await hasPermissionAsync(this.user, 'sync-auth-services-users'))) {\n\t\t\tthrow new Error('error-not-authorized');\n\t\t}\n\n\t\tif (settings.get('LDAP_Enable') !== true) {\n\t\t\tthrow new Error('LDAP_disabled');\n\t\t}\n\n\t\tawait LDAPEnterprise.sync();\n\t\tawait LDAPEnterprise.syncAvatarAndAbacAttributes();\n\n\t\treturn API.v1.success({\n\t\t\tmessage: 'Sync_in_progress' as const,\n\t\t});\n\t},\n);\n","sourceCodeStart":18,"sourceCodeEnd":51,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/ee/server/api/ldap.ts#L18-L51","documentation":"Error `error-not-authorized` thrown by ldap.syncNow when the authenticated user lacks the `sync-auth-services-users` permission. Only users holding that permission (typically admins) may trigger an LDAP sync; everyone else is rejected after auth succeeds.","triggerScenarios":"POST /v1/ldap.syncNow with valid credentials of a non-admin or an admin whose role lost sync-auth-services-users.","commonSituations":"Custom roles without the permission calling the sync; permission removed during role refactors; automation using a service account that was never granted it.","solutions":["Grant sync-auth-services-users to the calling user's role (Admin > Permissions), then retry.","Use an administrator account for LDAP sync operations.","Check the permission via the roles API in automation before calling sync."],"exampleFix":"// before\nawait POST('ldap.syncNow'); // as user without permission -> error-not-authorized\n\n// after\nawait POST('permissions.update', { permissions: [{ _id: 'sync-auth-services-users', roles: ['ldap-sync-bot'] }] });\nawait POST('ldap.syncNow');","handlingStrategy":"validation","validationCode":"const canSyncAuthServices = async (userId: string): Promise<boolean> =>\n\t(await GET('roles.list')()).roles.some((role) => role._id === 'admin'); // or query permissions for the caller","typeGuard":"const isNotAuthorized = (error: unknown): boolean =>\n\tBoolean(error && typeof error === 'object' && 'message' in error && (error as Error).message.includes('error-not-authorized'));","tryCatchPattern":"try {\n\tawait POST('ldap.syncNow');\n} catch (error) {\n\tif (isNotAuthorized(error)) {\n\t\tthrow new ForbiddenError('Caller needs sync-auth-services-users permission');\n\t}\n\tthrow error;\n}","preventionTips":["Run LDAP sync operations as a user holding sync-auth-services-users (typically admin).","Grant the permission explicitly to service accounts used for directory automation.","Re-check role permissions after role refactors."],"tags":["ee","ldap","permissions","rest-api"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}