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
- Build event names from the currently connected user (Meteor.userId()) and re-subscribe after every login/logout
- For room streams, join the room first or subscribe only from within it
- Read the stream's server-side rule to see exactly which predicate failed
- 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
- Build event names from the currently connected user and re-subscribe after every login/logout
- Only subscribe to room streams for rooms present in the user's subscriptions
- Read the stream's server-side read rule before assuming access
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.