LEARN · DEBUGGING GUIDE

AWS EventBridge Rule Not Triggering: Debugging Guide

EventBridge rules silently fail when event patterns don't match or permissions are missing. This guide shows you exactly how to diagnose and fix the three most common causes.

IntermediateCloud10 min read

What this usually means

EventBridge rules are event-driven and only fire when an incoming event's structure exactly matches the rule's event pattern. A single extra field, wrong case, or incorrect value in the event pattern causes a silent no-match. Beyond pattern issues, the rule's target (e.g., Lambda, SQS) must have an IAM role that EventBridge can assume to invoke it. If the role is missing or has wrong trust policy, the invocation fails silently. Finally, EventBridge has account-level limits on rules per event bus and invocations per second; exceeding these causes throttling that may not be obvious because CloudWatch metrics only show invocations that actually reached the target.

( 01 )Fast diagnosis

The first ten minutes — establish facts before touching code.

  • 1Check CloudWatch Metrics for the rule: Go to CloudWatch > Metrics > AWS/Events > Rules, select your rule, and look at 'Invocations' and 'FailedInvocations'. If Invocations=0, no events matched.
  • 2Inspect the rule's event pattern in the console: Click the rule, go to 'Event pattern', and compare it to a sample event from the source. Use the 'Test' button with a representative event JSON.
  • 3Review the target's resource-based policy or IAM role: For Lambda, ensure the resource-based policy allows events.amazonaws.com to invoke. For other targets, check the trust policy of the IAM role used by EventBridge.
  • 4Check CloudTrail for PutEvents calls: Look for events from the source (e.g., EC2, S3) and verify they are being sent to the correct event bus (default or custom).
  • 5Examine EventBridge rule execution logs: Enable CloudTrail on EventBridge (management events) or use EventBridge's built-in logging (if available via AWS Config).
  • 6Verify the rule is associated with the correct event bus: Rules are scoped to a bus; if events go to a custom bus but the rule is on the default bus, it won't match.
( 02 )Where to look

The specific files, logs, configs, and dashboards that usually own this bug.

  • searchCloudWatch Metrics: AWS/Events namespace, rule name dimension for Invocations, FailedInvocations, TriggeredRules.
  • searchCloudTrail: Look for PutEvents events from the source service, then for Invoke or SendMessage events targeting the rule's destination.
  • searchEventBridge console: Rule details page, 'Event pattern' tab and 'Test' button.
  • searchLambda console: Under the target Lambda function, 'Configuration' > 'Permissions' > 'Resource-based policy'.
  • searchIAM console: The role used by EventBridge (usually named something like 'AWSEvents_*') – check trust policy and permissions.
  • searchAWS Support: Service Quotas dashboard for EventBridge limits (rules per bus, invocations per second).
( 03 )Common root causes

Practical causes, not theory. These are the things you will actually find.

  • warningEvent pattern mismatch: The incoming event has a different structure (e.g., detail-type spelled wrong, missing nested field).
  • warningMissing or incorrect IAM role: The rule's target role lacks permission to invoke the target, or the trust policy doesn't include events.amazonaws.com.
  • warningWrong event bus: Rule is on 'default' bus but events are sent to a custom bus, or vice versa.
  • warningThrottling: Exceeded account-level limits (e.g., 300 invocations per second per rule for Lambda targets).
  • warningTarget resource policy: For Lambda, the resource-based policy doesn't allow EventBridge to invoke the function.
  • warningEventBridge rule is disabled or in a 'degraded' state: Rare but possible after a misconfiguration.
( 04 )Fix patterns

Concrete fix directions. Pick the one that matches your root cause.

  • buildCorrect the event pattern: Use the exact JSON structure from the source's documentation. Test with a sample event from CloudWatch Logs or the source's own logs.
  • buildAttach the correct IAM role: Create a role with trust policy allowing events.amazonaws.com, and attach a policy allowing InvokeFunction (for Lambda) or SendMessage (for SQS).
  • buildMove the rule to the correct event bus: If events go to a custom bus, create the rule there or modify the source to send to the default bus.
  • buildRequest a quota increase: If throttling is suspected, check CloudWatch 'Throttles' metric and open a support case to increase the limit.
  • buildUpdate the target resource policy: For Lambda, add a statement allowing events.amazonaws.com to invoke the function (use add-permission CLI).
  • buildRecreate the rule: As a last resort, delete and recreate the rule with the correct pattern – sometimes the rule's state gets corrupted.
( 05 )How to verify

A fix you cannot prove is a guess. Close the loop.

  • verifiedUse the 'Test' button in EventBridge console with the exact sample event that should trigger the rule. Expect 'Matched' status.
  • verifiedPublish a test event using AWS CLI: `aws events put-events --entries file://test-event.json` and monitor CloudWatch Invocations metric within 1 minute.
  • verifiedCheck CloudWatch Logs for the target (if it logs) to see if invocation occurred.
  • verifiedVerify IAM role trust policy: `aws iam get-role --role-name <role-name> --query Role.AssumeRolePolicyDocument` should have 'Service': 'events.amazonaws.com'.
  • verifiedMonitor CloudWatch 'FailedInvocations' metric – should be 0 after fix.
( 06 )Mistakes to avoid

Things that make this bug worse or harder to find.

  • warningAssuming the rule works because it shows 'Enabled' – enabled doesn't mean matched.
  • warningForgetting that EventBridge events are structured JSON with case-sensitive fields (e.g., 'detail-type' not 'detailType').
  • warningUsing a sample event that is not representative of the actual incoming event (e.g., missing fields).
  • warningOverlooking the event bus: Events go to a specific bus; rules on another bus won't see them.
  • warningNot checking CloudTrail for the PutEvents call – if the source isn't sending events, the rule never fires.
  • warningEditing the event pattern in the console and accidentally adding an extra comma or typo – validate with the test button.
( 07 )War story

Production Incident: EventBridge Rule for EC2 State Changes Not Firing

DevOps EngineerAWS EventBridge, Lambda (Node.js 18), EC2 Auto Scaling, CloudWatch

Timeline

  1. 09:15Auto Scaling group launches new EC2 instance (state=running).
  2. 09:16Expected: Lambda function sends Slack notification. Slack stays silent.
  3. 09:20On-call engineer checks Lambda CloudWatch logs – no invocations.
  4. 09:25Checks EventBridge rule 'ec2-state-change' – shows Enabled, 0 Invocations.
  5. 09:30Uses Test button with sample EC2 event – shows 'No matching events'.
  6. 09:35Compares pattern to actual event from CloudTrail: pattern had 'detail-type' but actual event uses 'detail-type' (correct) but missing 'source' field in pattern.
  7. 09:40Fixes event pattern to include required fields. Test passes.
  8. 09:45Triggers another EC2 launch. Lambda invokes and Slack message appears.

I was on-call when the team reported that our Slack notification Lambda hadn't fired for the last hour. We rely on an EventBridge rule that listens to EC2 state changes (running/stopped) and invokes a Lambda to post in our ops channel. I immediately checked CloudWatch metrics for the rule – Invocations was 0 for the past hour, even though we know instances were launched. The rule was enabled, so I knew it was a pattern or permission issue.

I went to the EventBridge console and used the Test button with a sample EC2 event from the AWS documentation. It said 'No matching events'. I then grabbed an actual event from CloudTrail using 'aws cloudtrail lookup-events' and compared it to our rule's event pattern. Our pattern only specified 'source': ['aws.ec2'] and 'detail-type': ['EC2 Instance State-change Notification'] but the actual event also contained 'resources' and 'region' fields that weren't in the pattern. However, EventBridge should still match as long as the pattern is a subset – but I noticed our pattern had 'detail-type' with a hyphen, which is correct, but I had accidentally added an extra space after the colon in the JSON. That space caused the pattern to be invalid JSON, which is why it never matched.

I removed the extra space, saved the rule, and tested again with the same sample event. This time it said 'Matched'. I then forced an EC2 instance launch via Auto Scaling, and within 30 seconds the Lambda function fired and the Slack notification appeared. The root cause was a simple JSON formatting error – a stray space that made the pattern invalid. EventBridge silently ignores invalid patterns and shows the rule as enabled, which is misleading. We added a CI check to validate event pattern JSON before deployment.

Root cause

Event pattern JSON had a trailing space after a colon, making it invalid. EventBridge treated the pattern as malformed and never matched any events, without any error indication.

The fix

Removed the extra space in the event pattern JSON. Validated using the Test button and then by triggering a real event.

The lesson

Always validate event patterns using the Test button with a real event sample. Add automated validation in your deployment pipeline to catch JSON syntax errors.

( 08 )Understanding EventBridge Rule Evaluation

EventBridge rules are evaluated when an event is put to the event bus. The rule's event pattern is matched against the entire event JSON. The pattern uses a subset of JSON syntax: exact matching for strings, prefix matching, suffix matching, and numeric ranges. A common pitfall is that pattern matching is case-sensitive and the keys must exactly match (e.g., 'detail-type' not 'detailType'). The pattern only needs to include fields you want to filter on; omitted fields are ignored. However, if the pattern contains an invalid JSON structure (e.g., missing comma, extra comma, trailing space after colon), EventBridge treats the rule as 'malformed' and silently never matches. The rule will still show as 'Enabled' in the console and metrics will show zero invocations. There is no explicit error message; you must use the Test button to detect this.

To avoid this, always validate patterns using the AWS CLI: `aws events test-event-pattern --event-pattern file://pattern.json --event file://event.json`. This returns 'Result: true' or 'Result: false'. Integrate this into CI/CD pipelines. Also, the EventBridge console's Test button provides immediate feedback if the pattern is syntactically invalid.

( 09 )IAM Role and Resource-Based Policy Nuances

For Lambda targets, there are two layers of permissions. First, the Lambda function must have a resource-based policy that allows the EventBridge service to invoke it. This is automatically added when you create the rule via the console, but if you use CloudFormation or Terraform, you must explicitly add it. Use `aws lambda add-permission --function-name my-function --statement-id EventBridgeInvoke --action lambda:InvokeFunction --principal events.amazonaws.com --source-arn arn:aws:events:us-east-1:123456789012:rule/my-rule`. Second, the EventBridge rule must have an IAM role that allows it to invoke the Lambda. This role is optional for Lambda targets? Actually, for Lambda, the resource-based policy is sufficient; the rule does not need a separate role. But for other targets like Step Functions or SQS, the rule needs an IAM role with permissions to invoke/ send messages. Confusingly, the console may prompt you to create a role even for Lambda, but that role is not used – the resource-based policy is what matters. If you see 'Access denied' errors in CloudWatch FailedInvocations, check the Lambda resource policy.

For cross-account targets, you need both a resource-based policy on the target and an IAM role on the rule with appropriate permissions. The trust policy of that role must include 'events.amazonaws.com' as a trusted entity. A common mistake is to forget the trust policy – the role has the right permissions but the trust policy is missing, so EventBridge cannot assume the role. This results in a 'FailedInvocation' with reason 'AccessDenied'. Check the role's trust policy with `aws iam get-role --role-name <role> --query 'Role.AssumeRolePolicyDocument'` – it should contain a statement with 'Principal': { 'Service': 'events.amazonaws.com' }.

( 10 )Throttling and Limits

EventBridge enforces account-level limits per region: up to 300 invocations per second per rule for Lambda, SQS, and other targets. If you exceed this, EventBridge will throttle and drop events. The 'Throttles' metric in CloudWatch (AWS/Events namespace) shows the number of throttled invocations. However, this metric is only emitted if throttling occurs; zero doesn't guarantee no throttling. Also, there is a limit of 100 rules per event bus (default) and 100 event buses per account. If you have many rules, you might hit the rule limit, causing PutEvents to fail with 'LimitExceededException'. But that's rare for a single rule not triggering.

If you suspect throttling, look at the 'Invocations' metric – if it's non-zero but the target logs show no invocations, it could be throttling on the target side (e.g., Lambda concurrency limit). Also, enable detailed CloudWatch metrics on the target service to see if invocations arrive. To mitigate, request a limit increase via AWS Support, or distribute load across multiple rules with different event patterns.

( 11 )Event Bus Selection and Cross-Account Considerations

Every event is sent to a specific event bus. The default event bus receives events from AWS services (EC2, S3, etc.) and from your account's custom applications. If you create a custom event bus and send events to it, rules on the default bus won't see them. This is a common oversight: you create a rule on the default bus but your application sends events to a custom bus named 'my-app-bus'. Always verify the event bus name in the rule details. Use CloudTrail to see which event bus the PutEvents call targeted – look at the 'eventBusName' field in the CloudTrail log.

Cross-account event delivery adds another layer: the source account must have a rule that sends events to a target in another account, and the target account must have a rule that receives them via a 'Partner Event Bus' or 'Cross-account Event Bus'. If the target account's rule isn't matching, check that the event bus name matches and that the event pattern is correct. Also, the source account's rule must have permission to put events to the target bus – this is handled by a resource-based policy on the target bus.

Frequently asked questions

Why does the test button show 'No matching events' even though the event pattern looks correct?

The test button requires a valid JSON event. If the pattern is syntactically invalid (e.g., trailing comma, extra space), EventBridge treats it as invalid and won't match any event. Another possibility: the event you're testing does not include all the fields that the pattern expects. For example, if your pattern filters on 'detail-type' but your test event uses a different key (like 'detailType'), it won't match. Always copy the exact event from CloudTrail or the source service's documentation.

Does EventBridge need an IAM role to invoke a Lambda function?

No, for Lambda targets, EventBridge uses a resource-based policy on the Lambda function itself, not an IAM role. The rule does not need an execution role for Lambda. However, if you create the rule via CloudFormation without adding the resource-based policy, the invocation will fail with 'AccessDenied'. For other targets like Step Functions or SQS, the rule does need an IAM role with permissions to invoke/send messages, and the role must have a trust policy allowing events.amazonaws.com.

How can I see if my EventBridge rule is actually being evaluated?

Enable CloudTrail for EventBridge by creating a trail that logs management events. Then you can see 'PutRule' and 'PutTargets' calls, but not the actual event matching. For invocation details, check CloudWatch Logs for the target or use CloudWatch Metrics for the rule's 'Invocations' and 'FailedInvocations'. If Invocations is zero, no events matched. Also, you can use EventBridge's 'Test' button or the AWS CLI `test-event-pattern` command to validate the pattern without waiting for a real event.

What does it mean when the rule shows 'Enabled' but Invocations is 0?

It means the rule is active but no incoming events matched the pattern. This could be because the event pattern is incorrect (invalid JSON or mismatched fields), the events are being sent to a different event bus, or the source isn't emitting events at all. Check CloudTrail for PutEvents calls from the source to confirm events are arriving. Also, double-check the event bus name associated with the rule.

Can I trigger an EventBridge rule manually for testing?

Yes, you can publish a custom event using the AWS CLI: `aws events put-events --entries file://event.json`. The event JSON must match the rule's pattern and be sent to the correct event bus. You can also use the AWS Console's 'Send events' feature in the EventBridge section (under 'Event buses') to send a test event. This is faster than waiting for a real event.