AWS EventBridge Error: Rule Target Invocation Throttled and Events Dropped
Fix AWS EventBridge rules that fail to invoke targets due to throttling: diagnose FailedInvocations, target concurrency limits, retries, and dead-letter queues.
- #automation
- #devops
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
Amazon EventBridge matches events to rules and invokes each rule’s targets. When a target cannot keep up — a Lambda hitting its concurrency limit, an API being rate-limited — EventBridge’s invocations are throttled and, after exhausting retries, the events are dropped or sent to a dead-letter queue. There is no exception thrown at your code; the signal appears in CloudWatch metrics and, if configured, the DLQ:
EventBridge metric: FailedInvocations > 0
EventBridge metric: ThrottledRules > 0
Lambda metric: Throttles > 0 (Rate Exceeded)
A DLQ message carries the reason in its attributes:
ERROR_CODE: RATE_EXCEEDED
ERROR_MESSAGE: The request was throttled because the target is being invoked faster than it can process.
RULE_ARN: arn:aws:events:us-east-1:123456789012:rule/order-events
Symptoms
- EventBridge
FailedInvocationsand/orThrottledRulesmetrics are non-zero. - A Lambda target shows
ThrottlesandRate Exceedederrors. - Events silently do not trigger their automation; downstream state lags.
- Messages appear in the rule target’s dead-letter queue with
RATE_EXCEEDED. - The problem spikes during event bursts and subsides when volume drops.
Common Root Causes
- Lambda concurrency limit — the target function’s reserved/account concurrency is lower than the event burst rate, so invocations are throttled.
- Downstream API rate limit — the target calls an external API that throttles, and the failures propagate as invocation failures.
- No DLQ configured — throttled events exhaust retries and are dropped with no record.
- Burst beyond retry window — EventBridge’s retry policy (max attempts / max event age) expires before the target recovers.
- Insufficient batching — one event per invocation instead of batching multiplies the invocation rate.
- Shared concurrency starvation — several functions share account concurrency and one hot path starves the target.
Diagnostic Workflow
Check the rule’s failure and throttle metrics:
aws cloudwatch get-metric-statistics --namespace AWS/Events \
--metric-name FailedInvocations --dimensions Name=RuleName,Value=order-events \
--start-time 2026-07-09T00:00:00Z --end-time 2026-07-09T03:00:00Z \
--period 300 --statistics Sum
Check whether the Lambda target is being throttled:
aws cloudwatch get-metric-statistics --namespace AWS/Lambda \
--metric-name Throttles --dimensions Name=FunctionName,Value=process-order \
--start-time 2026-07-09T00:00:00Z --end-time 2026-07-09T03:00:00Z \
--period 300 --statistics Sum
Inspect the function’s concurrency configuration:
aws lambda get-function-concurrency --function-name process-order
aws lambda get-account-settings --query 'AccountLimit.ConcurrentExecutions'
Confirm the rule target has retry and DLQ settings:
aws events list-targets-by-rule --rule order-events \
--query 'Targets[].{Id:Id,Retry:RetryPolicy,DLQ:DeadLetterConfig}'
Inspect DLQ messages for the throttle reason:
aws sqs receive-message --queue-url <dlq-url> \
--message-attribute-names All --max-number-of-messages 5 \
--query 'Messages[].MessageAttributes'
Example Root Cause Analysis
An order-processing pipeline began “missing” orders during peak. EventBridge FailedInvocations spiked at the top of each hour, and the process-order Lambda showed hundreds of Throttles. get-function-concurrency revealed a reserved concurrency of 10, while burst traffic drove ~120 concurrent invocations. EventBridge retried, but with no DLQ configured the throttled events were dropped after the retry window — which is why orders simply vanished with no error anywhere in the app.
Two fixes were applied. First, the Lambda’s reserved concurrency was raised and the downstream database call was made to use connection pooling so higher concurrency did not just move the bottleneck. Second — and non-negotiable — a dead-letter queue was attached to the rule target with an explicit RetryPolicy, so any future throttled event lands in the DLQ with a RATE_EXCEEDED attribute instead of disappearing:
RetryPolicy: { MaximumRetryAttempts: 10, MaximumEventAgeInSeconds: 3600 }
DeadLetterConfig: { Arn: arn:aws:sqs:...:order-events-dlq }
After the change, a subsequent burst that briefly exceeded capacity landed a handful of events in the DLQ, which were replayed once concurrency recovered — zero orders lost.
Prevention Best Practices
- Always attach a dead-letter queue to EventBridge rule targets so throttled or failed events are captured, never silently dropped.
- Size the target’s concurrency (Lambda reserved concurrency, downstream connection limits) to the expected burst, not the average.
- Set an explicit
RetryPolicywith a max event age long enough to ride out short throttle windows. - Alarm on
FailedInvocations,ThrottledRules, and targetThrottlesso throttling is visible before events are lost. - Batch where possible to reduce invocation rate, and smooth bursts with a queue between EventBridge and the worker if the target cannot scale fast.
- Build a DLQ replay path so captured events can be reprocessed after capacity recovers.
Quick Command Reference
# Rule failure/throttle metrics
aws cloudwatch get-metric-statistics --namespace AWS/Events \
--metric-name FailedInvocations --dimensions Name=RuleName,Value=<rule> \
--period 300 --statistics Sum --start-time <t0> --end-time <t1>
# Target Lambda throttles + concurrency
aws cloudwatch get-metric-statistics --namespace AWS/Lambda \
--metric-name Throttles --dimensions Name=FunctionName,Value=<fn> \
--period 300 --statistics Sum --start-time <t0> --end-time <t1>
aws lambda get-function-concurrency --function-name <fn>
# Confirm retry + DLQ on the target
aws events list-targets-by-rule --rule <rule> \
--query 'Targets[].{Retry:RetryPolicy,DLQ:DeadLetterConfig}'
# Read DLQ reason
aws sqs receive-message --queue-url <dlq-url> --message-attribute-names All
Conclusion
EventBridge throttling is dangerous precisely because it is silent: there is no exception in your code, just a metric ticking up and events quietly failing to fire their automation. The two-part fix is to give the target enough concurrency to absorb bursts and — more importantly — to attach a dead-letter queue and retry policy so any event that still can’t be delivered is captured with a RATE_EXCEEDED reason and can be replayed. Alarm on the failure metrics so you find out from CloudWatch, not from a customer asking where their order went.
Fixed it? Get 500 Automation & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.