RocketChat/Rocket.Chat · warning · Error

error-e2e-key-reset-in-progress

error-e2e-key-reset-in-progress

Error message

error-e2e-key-reset-in-progress

What it means

Thrown by POST e2e.resetRoomKey when LockMap already has an entry for rid — another resetRoomKey request for the same room is in flight on this server. It is an in-memory per-server concurrency lock. It is transient and thrown as a plain Error (not Meteor.Error). IMPORTANT: a related defect in this same handler (see error 389) can leak the lock, making this error permanent for an affected room until restart.

Source

Thrown at apps/meteor/server/api/v1/e2e.ts:445

			authRequired: true,
			body: isE2EResetRoomKeyProps,
			response: {
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
				403: validateForbiddenErrorResponse,
				200: ajv.compile<void>({
					type: 'object',
				}),
			},
		},

		async function action() {
			const { rid, e2eKey, e2eKeyId } = this.bodyParams;
			if (!(await hasPermissionAsync(this.user, 'toggle-room-e2e-encryption', rid))) {
				return API.v1.forbidden('error-not-allowed');
			}
			if (LockMap.has(rid)) {
				throw new Error('error-e2e-key-reset-in-progress');
			}

			LockMap.set(rid, true);

			if (!(await canAccessRoomIdAsync(rid, this.userId))) {
				throw new Error('error-not-allowed');
			}

			try {
				await resetRoomKey(rid, this.userId, e2eKey, e2eKeyId);
				return API.v1.success();
			} catch (e) {
				console.error(e);
				return API.v1.failure('error-e2e-key-reset-failed');
			} finally {
				LockMap.delete(rid);
			}
		},

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Wait for the in-flight reset to finish, then retry once.
  2. Debounce/disable the reset button client-side until the response arrives.
  3. If the error persists indefinitely, restart the server process to clear a leaked lock, and apply the fix in error 389.
Defensive patterns

Strategy: retry

Validate before calling

// track in-flight resets client-side per room
if (inFlightResets.has(rid)) { /* wait or skip */ }

Try / catch

for (const delay of [500, 1000, 2000]) {
  try { return await resetRoomKey({ rid, e2eKey, e2eKeyId }); }
  catch (e) {
    if (e?.message === 'error-e2e-key-reset-in-progress') { await sleep(delay); continue; }
    throw e;
  }
}
throw new Error('room key reset stayed locked');

Prevention

When it happens

Trigger: User double-clicks reset; client auto-retries; two admins reset the same room key at once; a prior request that failed the access check left the lock set (lock-leak bug).

Common situations: Impatient double-submit; network retry storm; prior access-denied attempt poisoned the room (see 389).

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/59076c346931c2e5. Report an issue: GitHub.