EventBridge event pattern syntax
Every EventBridge event-pattern operator with its exact syntax — exact values, prefix and suffix (and case-insensitive prefix), anything-but (value, prefix, suffix, wildcard), numeric ranges, cidr, exists, equals-ignore-case, wildcard, $or, empty and null — plus the constraints that make rules fail or silently miss events (leaf-only operators, numbers as doubles beyond ±2^53, wildcard and $or complexity limits, duplicate keys, exact case-sensitive matching).
markdownreferencev4A5EN-YQHVstage: referencetrust: officialservice: eventbridgeinterface: anyEventBridge event patternevent pattern syntaxprefix matchsuffix matchanything-butnumeric matchingcidr IPexistsequals-ignore-casewildcard$ornull matchempty string matchInvalidEventPatternExceptionevent pattern case sensitivedetail-typesourcepattern not matchingTestEventPatternCloudTrail event pattern
A pattern mirrors the event's JSON: each field you name must match one of the values in its list, and fields you don't name are ignored. Matching is exact and case-sensitive unless you use equals-ignore-case. Test against a real event with TestEventPattern (guides/eventbridge/route-events.md).
{
"source": ["com.example.orders"],
"detail-type": ["OrderPlaced"],
"detail": { "status": ["PAID", "SHIPPED"], "total": [{ "numeric": [">", 100] }] }
}
Operators
| Match | Syntax (as a value inside the field's list) |
|---|---|
| Exact (any of) | "state": ["running", "stopped"] |
| Prefix | "time": [{ "prefix": "2017-10-02" }] |
| Prefix, ignoring case | "service": [{ "prefix": { "equals-ignore-case": "EventB" } }] |
| Suffix | "FileName": [{ "suffix": ".png" }] |
| Anything but | "state": [{ "anything-but": "initializing" }] |
| Anything but prefix / suffix / wildcard | [{ "anything-but": { "prefix": "init" } }], [{ "anything-but": { "suffix": ".txt" } }], [{ "anything-but": { "wildcard": "*/lib/*" } }] |
| Numeric | "c-count": [{ "numeric": [">", 0, "<=", 5] }], [{ "numeric": ["<", 10] }], [{ "numeric": ["=", 3.018e2] }] |
| IP range | "sourceIPAddress": [{ "cidr": "10.0.0.0/24" }] |
| Field present | "state": [{ "exists": true }] |
| Case-insensitive | "detail-type": [{ "equals-ignore-case": "ec2 instance state-change notification" }] |
| Wildcard | "FileName": [{ "wildcard": "dir/*.png" }] |
| Empty string / null | "LastName": [""] / "UserID": [null] |
| OR across fields | "detail": { "$or": [ { "c-count": [{ "numeric": [">", 0, "<=", 5] }] }, { "d-count": [{ "numeric": ["<", 10] }] } ] } |
Constraints
- Leaf fields only: comparison operators and
existsapply to leaf fields, except$orandanything-but. - Numbers are compared as 64-bit doubles.
- Integers match exactly only within ±9,007,199,254,740,992 (2^53).
- A pattern number outside that range, or one that can't be represented exactly, makes rule creation fail.
- An event value like that isn't treated as a number and doesn't match.
- Wildcards:
- only in event bus rules;
- any number of
*, but not consecutive ones; - escape a literal
*as\*and a literal\as\\; no other escapes; - overly complex patterns raise
InvalidEventPatternException. $or: the total combinations (the product of each$orarray's length) must stay at or under 1,000, or the API raisesInvalidEventPatternException.- Duplicate keys: only the last occurrence counts. Easy to miss when patterns are generated.
Why a pattern doesn't match
| Cause | Fix | Check |
|---|---|---|
Case or punctuation differs (arn:…:function:x vs …/x) | Copy the exact strings from a real event | aws events test-event-pattern --event-pattern file://p.json --event file://e.json with a real event |
Matching on resources for CloudTrail "AWS API Call via CloudTrail" events | Those events have no resources field. Match fields under detail | Same call: the real event has no resources |
Matching a number sent as a string ("total": "250") | numeric only matches JSON numbers (the hub's reading of "not treated as numbers") | The real event's JSON: quoted value? |
| Rule in the wrong Region for IAM or Route 53 events | Global-service events arrive only in us-east-1 | aws events describe-rule --name <r> --region us-east-1 |
| Pattern just edited | Changes take a short time to apply. Check TriggeredRules | TriggeredRules for the rule |
SNS subscription filters use similar operators with different limits (reference/sns/filter-policies.md).