meteor/meteor · error · Meteor.Error

403

403

Error message

Access denied. No allow validators set on restricted collection for method '${method}'.

What it means

When a collection is in restricted mode (allow/deny rules have been defined via Collection.allow/deny) but no allow validators are registered for the given mutation method, the server short-circuits and rejects the client mutation with 403. The presence of deny rules or a restricted flag without any allow rule means nothing is permitted for that operation.

Source

Thrown at packages/allow-deny/allow-deny.js:185

            }
            return self._collection[method].apply(self._collection, args);
          }

          // This is the server receiving a method call from the client.

          // We don't allow arbitrary selectors in mutations from the client: only
          // single-ID selectors.
          if (!isInsert(method)) throwIfSelectorIsNotId(args[0], method);

          const syncMethodName = method.replace('Async', '');
          const syncValidatedMethodName = '_validated' + method.charAt(0).toUpperCase() + syncMethodName.slice(1);
          // it forces to use async validated behavior
          const validatedMethodName = syncValidatedMethodName + 'Async';

          if (self._restricted) {
            // short circuit if there is no way it will pass.
            if (self._validators[syncMethodName].allow.length === 0) {
              throw new Meteor.Error(
                403,
                'Access denied. No allow validators set on restricted ' +
                  "collection for method '" +
                  method +
                  "'."
              );
            }

            args.unshift(this.userId);
            isInsert(method) && args.push(generatedId);
            return self[validatedMethodName].apply(self, args);
          } else if (self._isInsecure()) {
            if (generatedId !== null) args[0]._id = generatedId;
            // In insecure mode we use the server _collection methods, and these sync methods
            // do not exist in the server anymore, so we have this mapper to call the async methods
            // instead.
            const syncMethodsMapper = {
              insert: "insertAsync",

View on GitHub (pinned to 5076d2f818)

Solutions

  1. Add an allow rule for the specific method that is failing (e.g. Collection.allow({ insert: ... })).
  2. Confirm the method name in the error (insert/update/remove) and ensure an allow rule of that name exists and returns true for the user/document.
  3. If the operation should never run from the client, move it to a trusted server-side Meteor.method that uses the collection directly.
  4. Audit all client-side mutations and ensure each has a corresponding allow rule.

Example fix

// before — allow rules missing insert
Posts.allow({
  update: (userId, doc) => userId === doc.owner,
  remove: (userId, doc) => userId === doc.owner,
});
// client: Posts.insert({...}) -> 403

// after
Posts.allow({
  insert: (userId, doc) => userId && doc.owner === userId,
  update: (userId, doc) => userId === doc.owner,
  remove: (userId, doc) => userId === doc.owner,
});
Defensive patterns

Strategy: validation

Validate before calling

// Server-side audit helper: ensure every client mutation has an allow rule.
function assertAllowRules(Collection, methods) {
  for (const m of methods) {
    const allows = (Collection._validators?.[m]?.allow) || [];
    if (allows.length === 0) {
      console.warn(`Collection ${Collection._name} has no allow rules for ${m}`);
    }
  }
}

Type guard

const hasAllowForMethod = (Collection, method) =>
  (Collection._validators?.[method]?.allow?.length ?? 0) > 0;

Try / catch

// client
try {
  await collection.insertAsync(doc);
} catch (e) {
  if (e.error === 403 && /No allow validators/.test(e.reason)) {
    notifyUser('You do not have permission to perform this action.');
  } else throw e;
}

Prevention

When it happens

Trigger: A client calls insert/update/remove (or async variants) on a collection where Collection.allow(...) was called but only registered rules for a different method (e.g. allow for update but client does insert), or only deny rules exist. Also when allow rules exist but none apply to the current method type.

Common situations: Defining allow rules for update/remove but forgetting insert (or vice versa). Using deny-only rules. Adding a new collection operation client-side without a matching allow rule. Migrating from insecure mode to secure mode incrementally.

Understand the failure class

Related errors


AI-assisted analysis of meteor/meteor@5076d2f818 (2026-08-13). Data as JSON: /api/errors/5a93fbc8e4e34362. Report an issue: GitHub.