n8n-io/n8n · warning · AdmittanceRejectedError

admittance_rejected

admittance_rejected

Error message

Execution admittance rejected: ${reason}

What it means

AdmittanceRejectedError (code: admittance_rejected) thrown by StartExecutionService.start() after graph validation passes but the admittance service (this.admittance.evaluate) returns a decision with accept === false. The decision.reason is interpolated into the message. Notably, nothing is persisted for rejected executions — they fail before executionStore.createExecution is called, so no execution record exists.

Source

Thrown at packages/@n8n/engine/src/execution/start-execution.service.ts:34

	executionId: string;
}

export class StartExecutionService {
	constructor(
		private readonly admittance: AdmittanceService,
		private readonly executionStore: ExecutionStore,
		private readonly workQueue: WorkQueue<OrchestrationMessage>,
		private readonly validateGraph: (graph: WorkflowGraph) => void = validateExecutableGraph,
	) {}

	async start(request: StartExecutionRequest): Promise<StartExecutionResult> {
		// Rejected before admittance: a graph that can never run shouldn't spend
		// admittance capacity, and nothing is persisted for it.
		this.validateGraph(request.graph);

		const decision = await this.admittance.evaluate({ workflowId: request.workflowId });
		if (!decision.accept) {
			throw new AdmittanceRejectedError(decision.reason);
		}

		const { id } = await this.executionStore.createExecution({
			workflowId: request.workflowId,
			// admitted; a worker flips this to 'running' when it starts
			status: 'queued',
			mode: request.mode ?? 'production',
			graph: request.graph,
			triggerPayload: request.triggerPayload ?? null,
		});

		// TODO(CAT-2938): the persist above and this publish aren't atomic — a
		// crash between them leaves the execution 'queued' until the
		// reconciliation sweep (not yet built) re-dispatches it.
		await this.workQueue.publish({
			type: 'execution:enqueued',
			executionId: id,
		});

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Inspect decision.reason — it tells you which limit/policy fired; address that specifically (raise concurrency, clear quota, exit maintenance).
  2. If concurrent-execution limit is hit, await an in-flight execution or raise the configured cap.
  3. For rate/quota rejections, back off and retry with jitter, or upgrade the plan / adjust the policy.
  4. If maintenance mode is on, exit it before submitting executions.
  5. Since nothing is persisted on rejection, instrument caller-side metrics to track rejection reasons.

Example fix

// before
const result = await startExecution.start(request);

// after
const decision = await admittance.evaluate({ workflowId: request.workflowId });
if (!decision.accept) {
  // schedule a retry with backoff, or surface to the user
  throw new UserError(`Execution not admitted: ${decision.reason}`);
}
const result = await startExecution.start(request);
Defensive patterns

Strategy: try-catch

Validate before calling

const decision = await admittance.evaluate({ workflowId: request.workflowId });
if (!decision.accept) {
  // do not call start; schedule a retry with backoff or surface to user
}

Type guard

function isAdmittanceRejected(err: unknown): boolean {
  return err instanceof AdmittanceRejectedError || (err instanceof Error && /^Execution admittance rejected:/.test(err.message));
}

Try / catch

try {
  await start(request);
} catch (err) {
  if (isAdmittanceRejected(err)) {
    // inspect decision.reason; back off, queue, or fail open per policy
  } else throw err;
}

Prevention

When it happens

Trigger: Calling start() for a workflow when admittance denies it — e.g. concurrent-execution limits reached, per-workflow rate limits, quota exhaustion, a global 'executions paused' state, or resource-based back-pressure. The admittance service's policy determines the reason.

Common situations: A trigger firing while the workflow is already at its max-concurrent-executions; an org over plan quota; maintenance mode; a worker pool saturated so admittance conservatively rejects; misconfigured admittance policy that is too strict.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/cd1133fc98c306cc. Report an issue: GitHub.