> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/ai-sre/3.0/ai-sre-for-administrators/set-up-alert-management/alert-rules/use-cel-alert-rules.md).

# Use CEL Expressions in Alert Rules

CEL (Common Expression Language) expressions provide advanced conditional logic for alert rule conditions beyond simple field comparisons.

CEL expressions cannot be tested or previewed before they execute. Syntax validation occurs when you save, but runtime errors only appear in execution logs. Test triggers in non-production environments first.

{% hint style="info" %}
**FEATURE FLAG REQUIRED**

CEL expression mode requires the `IR_CEL_CONDITIONS` feature flag. Contact your Harness account team to enable this feature.
{% endhint %}

### When to use CEL expressions to route alerts <a href="#when-to-use-cel-expressions-to-route-alerts" id="when-to-use-cel-expressions-to-route-alerts"></a>

Use CEL expressions when you need:

* **Regex pattern matching**: Filter alerts by service name patterns
* **Complex boolean logic**: Combine multiple conditions with custom precedence
* **String operations**: Check if alert titles contain specific text, match patterns
* **Numeric comparisons**: Filter by threshold values, error rates, percentages
* **Multi-value checks**: Use `in` operator for cleaner multi-value matching

***

### Available alert data in CEL expressions <a href="#available-alert-data-in-cel-expressions" id="available-alert-data-in-cel-expressions"></a>

**Standard alert fields**:

```cel
alert.id                 // Unique alert identifier
alert.title              // Alert title or summary
alert.priority           // p1_critical, p2_error, p3_warning, p4_info
alert.service            // Service name from alert payload
alert.source             // Alert source (datadog, newrelic, prometheus, etc.)
alert.timestamp          // When alert was received (milliseconds since epoch)
alert.fingerprint        // Deduplication fingerprint
alert.severity           // Severity from source system
alert.url                // Link to alert in source system
alert.environment        // Environment field from alert payload
```

**Custom alert fields**:

```cel
alert.custom_field_name      // Any custom field from your alert payload
```

***

### CEL alert rule examples <a href="#cel-alert-rule-examples" id="cel-alert-rule-examples"></a>

**Critical production alerts only**:

```cel
alert.severity == "critical" && alert.environment == "production"
```

**High-priority alerts from specific sources**:

```cel
alert.priority == "p1_critical" && alert.source in ["datadog", "newrelic"]
```

**Production API service alerts**:

```cel
alert.service.matches("^prod-.*-api$") && alert.severity == "critical"
```

**Error rate threshold**:

```cel
alert.error_rate > 0.05 && alert.environment == "production"
```

**Multiple service groups**:

```cel
alert.service.matches("^(payment|billing|subscription)-.*") &&
  alert.priority in ["p1_critical", "p2_error"]
```

**Alert title pattern matching**:

```cel
alert.title.contains("timeout") || alert.title.contains("connection refused")
```

**Source and region filtering**:

```cel
alert.source == "datadog" && alert.region.matches("^us-.*") && alert.priority == "p1_critical"
```

**Complex multi-condition logic**:

```cel
(alert.severity == "critical" && alert.environment == "production") ||
(alert.priority == "p1_critical" && alert.service.matches(".*-api$")) ||
alert.affected_users > 1000
```

***

### CEL operators to route alerts <a href="#cel-operators-to-route-alerts" id="cel-operators-to-route-alerts"></a>

**Comparison**:

```cel
==   Equal to
!=   Not equal to
<    Less than
<=   Less than or equal to
>    Greater than
>=   Greater than or equal to
```

**Logical**:

```cel
&&   AND
||   OR
!    NOT
```

**String operations**:

```cel
alert.service.matches("regex")          // Regex match
alert.title.contains("text")            // Contains substring
alert.service.startsWith("prefix")      // Starts with
alert.service.endsWith("suffix")        // Ends with
```

**List membership**:

```cel
alert.priority in ["p1_critical", "p2_error"]
alert.source in ["datadog", "newrelic", "prometheus"]
```

***

### Field-based conditions versus CEL <a href="#field-based-conditions-versus-cel" id="field-based-conditions-versus-cel"></a>

**Field-based conditions example**:

* Field: severity
* Operator: equals
* Value: critical
* AND
* Field: environment
* Operator: equals
* Value: production

**Equivalent CEL expression**:

```cel
alert.severity == "critical" && alert.environment == "production"
```

**CEL advantages**:

* More concise for complex conditions
* Regex pattern matching
* Calculations and numeric operations
* Flexible string operations
* Better for multi-value checks with `in` operator

***

### Best practices for CEL in alert rules <a href="#best-practices-for-cel-in-alert-rules" id="best-practices-for-cel-in-alert-rules"></a>

**1. Keep expressions simple and readable**:

```cel
// ✅ Clear and readable
alert.severity == "critical" && alert.environment == "production"

// ❌ Hard to parse
alert.severity=="critical"&&alert.environment=="production"||alert.priority=="p1_critical"
```

**2. Use explicit parentheses**:

```cel
// Clear precedence
(alert.severity == "critical" || alert.priority == "p1_critical") && 
alert.environment == "production"
```

**3. Add null checks for optional fields**:

```cel
// Safe null check
alert.custom_field != null && alert.custom_field == "value"
```

**4. Test with sample alerts**:

* Send test alerts through the webhook
* Verify alert rule fires as expected
* Check execution logs for errors
* Refine expression based on results

**5. Use `in` for multiple values**:

```cel
// ✅ Concise
alert.priority in ["p1_critical", "p2_error"]

// ❌ Verbose
alert.priority == "p1_critical" || alert.priority == "p2_error"
```

***

### Troubleshooting CEL in alert rules <a href="#troubleshooting-cel-in-alert-rules" id="troubleshooting-cel-in-alert-rules"></a>

<details>

<summary>Expression syntax errors when saving alert rule</summary>

Check for single = instead of ==, unclosed strings, missing parentheses, or typos in field names. Use the exact namespace prefix (alert.). The error message shows the position of the syntax error.

</details>

<details>

<summary>Field not found errors in alert rule CEL expression</summary>

Verify the field name matches exactly (case-sensitive) and exists in the alert payload. Use alert. prefix for all alert fields. For custom fields, ensure they are present in the incoming alert data.

</details>

<details>

<summary>Regex pattern not matching expected alerts</summary>

Test your regex pattern using an online regex tester. Escape special characters with backslashes. Use ^ for start of string and $ for end of string. Example: alert.service.matches( "^prod-api\\\\.") with escaped dot.

</details>

<details>

<summary>Null pointer errors when alert rule executes</summary>

Add null checks before accessing fields: alert.custom\_field != null && alert.custom\_field.contains("text"). Custom fields may not be present on every alert.

</details>

***

### Next steps <a href="#next-steps" id="next-steps"></a>

* Go to [Create Dynamic Content](/ai-sre/ai-sre-for-administrators/get-started/expression-languages.md) for complete CEL syntax reference, additional operators, and advanced patterns
* Go to [Route Alerts](/ai-sre/ai-sre-for-administrators/set-up-alert-management/alert-rules/overview.md) to learn about alert rule configuration
* Go to [Ingest Alerts](/ai-sre/ai-sre-for-administrators/set-up-alert-management/webhooks/overview.md) to set up incoming alert sources
