RocketChat/Rocket.Chat · error · Error
E2E encryption can only be enabled in secure contexts (HTTPS
Error message
E2E encryption can only be enabled in secure contexts (HTTPS)
What it means
Thrown by the E2E (end-to-end encryption) client's startClient method when the browser's isSecureContext flag is false. isSecureContext is a Web API that is true only when the page is served over HTTPS (or is localhost/127.0.0.1). E2E encryption relies on the Web Crypto API (specifically crypto.subtle), which is only available in secure contexts, so the client refuses to initialize without it.
Source
Thrown at apps/meteor/client/lib/e2ee/rocketchat.e2e.ts:347
onClose: imperativeModal.close,
onCancel: () => {
this.closeAlert();
imperativeModal.close();
},
onConfirm: () => {
removeStoredItem(STORAGE_KEYS.E2EE_RANDOM_PASSWORD);
this.setState('READY');
dispatchToastMessage({ type: 'success', message: t('E2E_encryption_enabled') });
this.closeAlert();
imperativeModal.close();
},
},
});
}
async startClient(userId: string): Promise<void> {
if (!isSecureContext) {
throw new Error('E2E encryption can only be enabled in secure contexts (HTTPS)');
}
const span = log.span('startClient');
if (this.userId === userId) {
return;
}
span.info(this.state);
this.userId = userId;
this.keychain = new Keychain(userId);
let { public_key, private_key } = this.getKeysFromLocalStorage();
await this.loadKeysFromDB();
if (!public_key && this.db_public_key) {
public_key = this.db_public_key;View on GitHub (pinned to f9d3ec372b)
Solutions
- Serve the Rocket.Chat client over HTTPS (configure TLS on the server or use a TLS-terminating reverse proxy).
- For local development, use http://localhost or http://127.0.0.1 — these are treated as secure contexts by browsers.
- If behind a reverse proxy (nginx, Traefik), ensure X-Forwarded-Proto: https is passed and ROOT_URL is set to https://.
- Disable E2E if HTTPS is not available and encryption is not required for the deployment.
Example fix
// before: served over http://chat.example.com // after: configure TLS // nginx config: // listen 443 ssl; // proxy_set_header X-Forwarded-Proto https; // ROOT_URL=https://chat.example.com
Defensive patterns
Strategy: validation
Validate before calling
if (!window.isSecureContext) {
// show user-facing error: HTTPS required for E2E
showE2ESecureContextError();
return;
}
await e2e.startClient(userId); Type guard
const isSecureContextAvailable = (): boolean => typeof window !== 'undefined' && window.isSecureContext === true;
Try / catch
try {
await e2e.startClient(userId);
} catch (e) {
if (e instanceof Error && e.message.includes('secure context')) {
dispatchToastMessage({ type: 'error', message: t('E2E_requires_https') });
return;
}
throw e;
} Prevention
- Always serve Rocket.Chat over HTTPS in production.
- For local development, use localhost (treated as a secure context).
- Set ROOT_URL to https:// and ensure reverse proxy passes X-Forwarded-Proto.
- Check window.isSecureContext before initialising E2E features.
When it happens
Trigger: The Rocket.Chat web client is served over plain HTTP (not HTTPS) and the hostname is not localhost. The app is loaded in an insecure iframe. A proxy or load balancer terminates TLS but the app origin is misconfigured as http://. Service worker or non-secure origin context.
Common situations: Self-hosted development/staging server without TLS configured. Behind a reverse proxy where X-Forwarded-Proto is not set correctly, so the Node server thinks it is HTTP. Using an IP address instead of localhost over plain HTTP. Migration from HTTP to HTTPS that left the ROOT_URL as http://.
Related errors
- Cannot reset room key
- The environmental variable "${envVarName}" is not readable.
- Search provider not found
- LDAP_disabled
- apps-engine-not-configured-correctly
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/e632a531b01b600f.
Report an issue: GitHub.