RocketChat/Rocket.Chat · error · MeteorError

error-not-authorized-federation

error-not-authorized-federation

Error message

Not authorized to access federation

What it means

Thrown from beforeAddUserToRoom when the invitee is not natively federated and FederationMatrix.canUserAccessFederation(user) returns false. That check fails when the user lacks the 'access-federation' permission, or — when the server validates user domains — when the user has no verified email address on the workspace's own domain. It guards both local invites into federated rooms and incoming federation traffic.

Solutions

  1. Grant the invitee the 'access-federation' permission (role assignment in Administration > Permissions)
  2. Have the user verify an email address on the workspace's federation domain, then retry the invite
  3. If the domain restriction is unintended, disable the user-domain validation setting for federation

Example fix

// before: inviting and only discovering the failure from the throw
await addUserToRoom(room._id, user, inviter);

// after: pre-check the exact gate the hook applies
import { FederationMatrix } from '@rocket.chat/core-services';
import { isUserNativeFederated } from '@rocket.chat/core-typings';
if (!isUserNativeFederated(user) && !(await FederationMatrix.canUserAccessFederation(user))) {
  // fix permissions / verified email first
  throw new Error('User cannot access federation: ' + user.username);
}
await addUserToRoom(room._id, user, inviter);
Defensive patterns

Strategy: validation

Validate before calling

import { FederationMatrix } from '@rocket.chat/core-services';
import { hasPermissionAsync } from '@rocket.chat/core-services';

const mayAccessFederation = async (userId: string): Promise<boolean> => {
  if (!(await hasPermissionAsync(userId, 'access-federation'))) return false;
  return FederationMatrix.canUserAccessFederation({ _id: userId } as any);
};

Try / catch

try {
  await addUserToRoom(rid, user, inviter);
} catch (err: any) {
  if (err?.error === 'error-not-authorized-federation') {
    // grant access-federation or have the user verify a domain email, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: Inviting a local user without the access-federation role into a federated room; having 'Federation (or validateUserDomain) restrict access by verified domain email' enabled while the invitee's email is unverified or on another domain; permission role changes that removed access-federation after the room was created.

Common situations: New users invited to a federated channel before their email was verified; admin removed access-federation from the default user roles; SSO provisioned emails on a secondary domain.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/6f1358f0b4dae59f. Report an issue: GitHub.

Appendix: source

Thrown at apps/meteor/ee/server/hooks/federation/index.ts:145

		if (subscription) {
			if (!isBannedSubscription(subscription)) {
				return;
			}
			// For federated rooms, unban requires a Matrix kick (leave) followed by a new invite.
			// Remove the subscription so the unban propagates to Matrix via the afterUnbanFromRoom callback,
			// then let the flow continue to create a new INVITED subscription via the beforeAddUserToRoom hook.
			await Subscriptions.removeById(subscription._id);

			await Message.saveSystemMessage('user-unbanned', room._id, user.username, inviter);

			void notifyOnSubscriptionChanged(subscription, 'removed');
			void notifyOnRoomChangedById(room._id);

			await afterUnbanFromRoomCallback.run({ unbannedUser: user, userWhoUnbanned: inviter }, room);
		}

		if (!isUserNativeFederated(user) && !(await FederationMatrix.canUserAccessFederation(user))) {
			throw new MeteorError('error-not-authorized-federation', 'Not authorized to access federation');
		}

		// If inviter is federated, the invite came from an external transaction.
		// Don't propagate back to Matrix (it was already processed at origin server).
		if (isUserNativeFederated(inviter)) {
			return;
		}

		await FederationMatrix.inviteUsersToRoom(room, [user.username], inviter);

		// after invite is sent we create the invite subscriptions
		// TODO this may be not needed if we receive the emit for the invite event from matrix
		await Room.createUserSubscription({
			ts: new Date(),
			room,
			userToBeAdded: user,
			inviter,
			status: 'INVITED',

View on GitHub (pinned to b2c16d5842)