RocketChat/Rocket.Chat · error · MeteorError

not-allowed

not-allowed

Error message

not-allowed

What it means

After the event-name check, the streamer evaluates the stream's read rule via isReadAllowed; Rocket.Chat registers per-stream ACLs (e.g. stream-notify-user events must belong to the connected user, room streams require access). Any result other than exactly true throws Meteor.Error 'not-allowed' and the subscription is refused.

Source

Thrown at apps/meteor/server/modules/streamer/streamer.module.ts:187

		if (typeof options === 'boolean') {
			useCollection = options;
		} else {
			if (options.useCollection) {
				useCollection = options.useCollection;
			}

			if (options.args) {
				args = options.args;
			}
		}

		if (eventName.length === 0) {
			throw new MeteorError('invalid-event-name');
		}

		if ((await this.isReadAllowed(publication, eventName, args)) !== true) {
			throw new MeteorError('not-allowed');
		}

		// after meteor 3.4.1 immediately after a disconnection session becomes null (which is not wrong)
		// we were just not counting on this, session is _session so we actually should not use it
		// now after any await, the session can potentially be null, so we need to check for that
		if (!Streamer.isPublicationActive(publication)) {
			// if the client is disconnected, we don't want to do anything, it will not have an disconnect event to undo anymore
			throw new MeteorError('publication-client-disconnected');
		}

		const subscription = {
			subscription: publication,
			eventName,
		};

		this.addSubscription(subscription, eventName);

		publication.onStop(() => {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Build event names from the currently connected user (Meteor.userId()) and re-subscribe after every login/logout
  2. For room streams, join the room first or subscribe only from within it
  3. Read the stream's server-side rule to see exactly which predicate failed
  4. If access should be granted, ask the server admin to extend the stream's allow-read rule

Example fix

// before
Meteor.subscribe('stream-notify-user', `${otherUserId}/notification`, false); // -> not-allowed

// after
Meteor.subscribe('stream-notify-user', `${Meteor.userId()}/notification`, false);
Defensive patterns

Strategy: try-catch

Validate before calling

const buildOwnUserEvent = (event: string): string => `${Meteor.userId()}/${event}`;
const buildOwnRoomEvent = (rid: string): string => rid; // and only subscribe to rooms you have a subscription for

Try / catch

Meteor.subscribe('stream-notify-user', eventName, false, {
  onError(error) {
    if (error instanceof Meteor.Error && error.error === 'not-allowed') {
      // user has no read access to this stream; drop the subscription and surface it in UI state
      onStreamAccessDenied(eventName);
    }
  },
});

Prevention

When it happens

Trigger: Subscribing to a stream event the rule set denies: another user's stream-notify-user/<otherUserId>/... events, a room stream for a room the user is not in, or streams gated by role or server setting.

Common situations: A DDP session kept open across a re-login still holding subscriptions keyed to the previous user; custom clients trying to listen to global or foreign streams; an admin tightening stream permissions while sessions were live.

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/eba14e16db414a14. Report an issue: GitHub.