RocketChat/Rocket.Chat · error · Error

Cannot reset room key

Error message

Cannot reset room key

What it means

Thrown by the useE2EEResetRoomKey mutation at two distinct points: (1) when e2e.getInstanceByRoomId(roomId) returns no E2E room instance (the room is not encrypted or the E2E client has not initialized an instance for it), and (2) when e2eRoom.resetRoomKey() returns no e2eKey or e2eKeyId (the key reset operation failed to produce a new key pair). The mutation posts the new key to /v1/e2e.resetRoomKey.

Source

Thrown at apps/meteor/client/views/room/hooks/useE2EEResetRoomKey.ts:21

import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';

import { e2e } from '../../../lib/e2ee';

type UseE2EEResetRoomKeyVariables = {
	roomId: IRoom['_id'];
};

export const useE2EEResetRoomKey = (
	options?: Omit<UseMutationOptions<void, Error, UseE2EEResetRoomKeyVariables>, 'mutationFn'>,
): UseMutationResult<void, Error, UseE2EEResetRoomKeyVariables> => {
	const resetRoomKey = useEndpoint('POST', '/v1/e2e.resetRoomKey');

	return useMutation({
		mutationFn: async ({ roomId }) => {
			const e2eRoom = await e2e.getInstanceByRoomId(roomId);
			if (!e2eRoom) {
				throw new Error('Cannot reset room key');
			}

			const { e2eKey, e2eKeyId } = (await e2eRoom.resetRoomKey()) ?? {};

			if (!e2eKey || !e2eKeyId) {
				throw new Error('Cannot reset room key');
			}

			try {
				await resetRoomKey({ rid: roomId, e2eKeyId, e2eKey });
			} catch (error) {
				throw error;
			}
		},

		...options,
	});
};

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify the room is E2E encrypted before showing the reset-key option.
  2. Ensure the E2E client is in READY state (check e2e.state) before calling the mutation.
  3. Catch the mutation error in the UI and show a descriptive message ('E2E not active for this room' vs 'key reset failed').
  4. If resetRoomKey returned no key, retry after confirming secure context and keychain availability.

Example fix

// before
const reset = useE2EEResetRoomKey();
reset.mutate({ roomId }); // no guard
// after
const reset = useE2EEResetRoomKey({
  onError: (error) => {
    if (error.message === 'Cannot reset room key') {
      dispatchToastMessage({ type: 'error', message: t('E2E_not_available_for_room') });
    }
  },
});
// only call when room is encrypted:
if (room.encrypted) {
  reset.mutate({ roomId });
}
Defensive patterns

Strategy: validation

Validate before calling

const e2eRoom = await e2e.getInstanceByRoomId(roomId);
if (!e2eRoom) {
  // room is not encrypted or E2E not initialized
  dispatchToastMessage({ type: 'error', message: t('E2E_not_active') });
  return;
}
// proceed with key reset

Type guard

const isRoomE2EEncrypted = async (roomId: string): Promise<boolean> => {
  return Boolean(await e2e.getInstanceByRoomId(roomId));
};

Try / catch

const reset = useE2EEResetRoomKey({
  onError: (error) => {
    if (error.message === 'Cannot reset room key') {
      dispatchToastMessage({ type: 'error', message: t('E2E_key_reset_failed') });
    }
  },
});

Prevention

When it happens

Trigger: The room is not E2E encrypted (no e2e instance exists for it). The E2E client has not finished initializing for this room (startClient not called or still pending). resetRoomKey() internally fails (key generation error, keychain access failure). The E2E keychain is locked or unavailable. Secure context requirements not met (see error 106).

Common situations: User tries to reset E2E key for a room that is not encrypted. E2E client is in a transitional state (not READY). Browser's crypto/keychain APIs unavailable (insecure context). Corrupted key material preventing reset. E2E setup incomplete (user hasn't set up their E2E password).

Related errors


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