RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-state
error-invalid-state
Error message
Invalid state provided
What it means
finishOAuthAuthorization is the last leg of the cloud OAuth flow. It compares the returned state parameter against the Cloud_Workspace_Registration_State setting stored when the flow started; a mismatch throws Meteor.Error 'error-invalid-state' — the standard OAuth CSRF state check failing for cloud registration.
Source
Thrown at apps/meteor/server/lib/cloud/finishOAuthAuthorization.ts:15
import { Users } from '@rocket.chat/models';
import { serverFetch as fetch } from '@rocket.chat/server-fetch';
import { Meteor } from 'meteor/meteor';
import { getRedirectUri } from './getRedirectUri';
import { userScopes } from './oauthScopes';
import { assertNotOfflineLicense } from './offlineLicense';
import { settings } from '../../settings';
import { SystemLogger } from '../logger/system';
export async function finishOAuthAuthorization(code: string, state: string) {
assertNotOfflineLicense();
if (settings.get<string>('Cloud_Workspace_Registration_State') !== state) {
throw new Meteor.Error('error-invalid-state', 'Invalid state provided', {
method: 'cloud:finishOAuthAuthorization',
});
}
const clientId = settings.get<string>('Cloud_Workspace_Client_Id');
const clientSecret = settings.get<string>('Cloud_Workspace_Client_Secret');
const scope = userScopes.join(' ');
let payload;
try {
const cloudUrl = settings.get<string>('Cloud_Url');
const response = await fetch(`${cloudUrl}/api/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
params: new URLSearchParams({
client_id: clientId,
client_secret: clientSecret,View on GitHub (pinned to b2c16d5842)
Solutions
- Restart the cloud registration from the Setup Wizard / Admin > Cloud so a fresh state is generated end-to-end.
- Ensure only one registration flow runs at a time on the workspace.
- Never bookmark or replay the OAuth callback URL.
Defensive patterns
Strategy: retry
Try / catch
try {
await Meteor.callAsync('cloud:finishOAuthAuthorization', code, state);
} catch (e) {
if (e instanceof Meteor.Error && e.error === 'error-invalid-state') {
// flow state stale/overwritten: restart registration from Admin > Cloud to mint a new state
}
throw e;
} Prevention
- Run only one cloud registration flow at a time per workspace (lock the wizard while active).
- Never reload or bookmark OAuth callback URLs.
- On any registration failure, restart the whole flow rather than retrying the callback step.
When it happens
Trigger: The cloud:finishOAuthAuthorization callback arrives with a state from an earlier or different registration flow: a second admin started a new flow (overwriting the setting), the callback URL was replayed, or the setting was reset mid-flow.
Common situations: Two people (or two tabs) running workspace registration simultaneously; a stale browser tab completing an old OAuth redirect; reusing an old callback link after a failed attempt.
Related errors
- error-invalid-user
- 401
- Failed to connect to Rocket.Chat Cloud: ${error}
- Failed to connect to Rocket.Chat Cloud: ${response.statusTex
- Invalid registration token
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/94070ee86c46f342.
Report an issue: GitHub.