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
- Inspect decision.reason — it tells you which limit/policy fired; address that specifically (raise concurrency, clear quota, exit maintenance).
- If concurrent-execution limit is hit, await an in-flight execution or raise the configured cap.
- For rate/quota rejections, back off and retry with jitter, or upgrade the plan / adjust the policy.
- If maintenance mode is on, exit it before submitting executions.
- 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
- Pre-evaluate admittance before doing expensive graph prep.
- Track rejection reasons in metrics — nothing is persisted on rejection.
- Tune admittance policy (concurrency, quotas) to match real workload.
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
- Rate limit exceeded. Please wait a moment and try again.
- admittance_rejected
- OpenAI: Rate limit reached
- EXECUTION_ERROR
- EXECUTION_ERROR
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/cd1133fc98c306cc.
Report an issue: GitHub.