Skip to content

Common Error Messages

Note

Quick reference for understanding and fixing the most common NQL error messages.

Overview

NQL error messages can be cryptic. This guide explains the most common errors, what causes them, and how to fix them quickly.

Critical Syntax Errors

"Cannot use compute after summarize"

Meaning: You're trying to calculate values using variables from a summarize clause in a subsequent compute clause.

Common cause: Attempting to reference summarize variables outside the summarize block.

Example of the error:

/* ❌ WRONG - This will fail */
execution.events during past 7d
| summarize
    total_cpu = cpu_time.sum(),
    total_duration = execution_duration.sum()
| compute cpu_percent = (total_cpu * 100) / total_duration  # ERROR!

Fix: Move all calculations inline within the summarize clause itself.

/* ✅ CORRECT - Calculation inside summarize */
execution.events during past 7d
| summarize
    cpu_percent = ((cpu_time.sum()) * 100) / execution_duration.sum()

The Rule

NEVER use compute after summarize. All calculations must be inline within the summarize clause.


"Field 'X' not found in context"

Meaning: The field you're referencing doesn't exist in the current query context.

Common causes: 1. Typo in field name - Check spelling and capitalization 2. Wrong table context - Field doesn't exist on the table you're querying 3. Missing join - Field requires include or with clause first 4. Wrong namespace - Using device.field when you should use context.field or vice versa

Examples of the error:

/* ❌ WRONG - device field on events without proper context */
execution.events during past 7d
| where device.hardware.memory > 8GB  # ERROR!

/* ✅ CORRECT - use context for event-time values */
execution.events during past 7d
| where context.hardware_memory > 8GB

/* ✅ CORRECT - or start with devices and join events */
devices
| with execution.events during past 7d
| where device.hardware.memory > 8GB

Quick check: See Field Reference to verify the field exists on your table.


"Time window required for event table"

Meaning: Event tables (execution.events, connection.events, etc.) require a time specification.

Example of the error:

/* ❌ WRONG - no time window */
execution.events
| summarize count = count()

Fix: Add during past Xd or during past Xh:

/* ✅ CORRECT - time window specified */
execution.events during past 7d
| summarize count = count()

Always Add Time Windows

Get in the habit of typing during past 7d immediately after event table names.


"Cannot reference variable within same summarize clause"

Meaning: You're trying to use a variable you just defined within the same summarize block.

Example of the error:

/* ❌ WRONG - referencing total_failures in same clause */
| summarize
    total_failures = (sum1 + sum2),
    failure_rate = total_failures / total_attempts  # ERROR!

Fix: Repeat the full calculation instead of referencing the variable:

/* ✅ CORRECT - repeat the calculation */
| summarize
    total_failures = (sum1 + sum2),
    failure_rate = (sum1 + sum2) / total_attempts

Performance Errors

"Query timeout exceeded" or "Query too complex"

Meaning: Your query is taking too long to execute (typically >60 seconds).

Common causes: 1. No early filtering - Processing too much data 2. Time window too large - Querying past 30d on execution.events without filters 3. Multiple includes without limits - Each include multiplies query complexity 4. Complex calculations on large datasets - Expensive operations without narrowing data first

Examples and fixes:

/* ❌ SLOW - no filters on large dataset */
execution.events during past 30d
| summarize count by binary.name  # Processes ALL events first!

/* ✅ FAST - filter early */
execution.events during past 30d
| where binary.name in ["outlook.exe", "chrome.exe", "teams.exe"]
| summarize count by binary.name
/* ❌ SLOW - huge time window */
execution.events during past 30d
| where binary.name = "outlook.exe"
| summarize count by device.name

/* ✅ FAST - reduce time window during development */
execution.events during past 7d  # Use smaller window first
| where binary.name = "outlook.exe"
| summarize count by device.name
| limit 10  # Add limit during testing

Development Strategy

  1. Start with past 1d or past 2d during development
  2. Add | limit 10 to see results quickly
  3. Remove limits and expand time window when query is optimized

See: Query Performance Guide for detailed optimization techniques.


"Exceeded retention limit"

Meaning: You're trying to query data beyond the retention period.

Retention limits:

  • execution.events / connection.events:
  • 8 days for high-res (past Xh, past Xmin)
  • 30 days for low-res (past Xd)
  • Most other event tables: 30 days standard retention

Example of the error:

/* ❌ May fail - exceeds 8-day high-res limit */
execution.events during past 15d
| where binary.name = "outlook.exe"

/* ✅ CORRECT - within limits */
execution.events during past 7d
| where binary.name = "outlook.exe"

Remember Retention Limits

  • High-res queries (past Xh): Max 8 days for execution.events/connection.events
  • Low-res queries (past Xd): Max 30 days for execution.events/connection.events

Data Type Errors

"Invalid operator for data type"

Meaning: You're using an operator that doesn't work with the field's data type.

Common examples:

  • Using > or < on string fields
  • Doing math on non-numeric fields

Examples and fixes:

/* ❌ WRONG - comparing strings with > */
devices
| where device.name > "SERVER"  # Doesn't work as expected

/* ✅ CORRECT - use wildcards for string matching */
devices
| where device.name = "SERVER*"
/* ❌ WRONG - math on string field */
devices
| compute total = device.name + device.os  # ERROR!

/* ✅ CORRECT - use proper numeric fields */
execution.events during past 7d
| compute total_cpu = cpu_time + gpu_time

Quick check: See Field Reference to verify field data types.


Logic Errors (Query Runs, Wrong Results)

Using count() on Sampled Events

Problem: count() on event tables returns the number of samples, not meaningful business metrics.

Example of the problem:

/* ❌ BAD - Returns sample count (not useful!) */
execution.events during past 7d
| summarize total_events = count()
/* Returns: 1,245,892 (sample count - meaningless!) */

Fix: Count unique objects instead:

/* ✅ CORRECT - Count unique objects */
execution.events during past 7d
| summarize
    unique_devices = device.count(),
    unique_applications = application.count(),
    unique_users = user.count()
/* Returns: 142 devices, 38 apps, 156 users (business value!) */

Or: Sum actual metrics:

/* ✅ CORRECT - Sum actual metrics */
execution.events during past 7d
| summarize
    total_cpu_time = cpu_time.sum(),
    total_memory_used = real_memory.sum()

Never Use count() on Events

Sampled events represent periodic measurements, not discrete occurrences. Use device.count(), application.count(), or field.sum() instead.


Confusing past 2d with past 48h

Problem: These are NOT equivalent and return different data!

Aspect past 2d past 48h
Resolution Daily aggregated 5-15 minute samples
Timezone Cloud instance timezone User's browser timezone
Precision Full calendar days Exact hour intervals

Example showing the difference:

/* Query 1: past 2d (low-res, cloud timezone) */
execution.events during past 2d
| summarize count = count()
/* Returns: Different range than past 48h! */

/* Query 2: past 48h (high-res, user timezone) */
execution.events during past 48h
| summarize count = count()
/* Returns: Different range and more granular data! */

Fix: Choose based on your need: - Use past Xd for: Trends, reports, dashboards - Use past Xh for: Troubleshooting, recent analysis, incident investigation


Query Debugging Workflow

When you encounter an error, follow these steps:

Step 1: Read the Error Message Carefully

  • Look for specific field names mentioned
  • Note if it mentions "syntax", "field", "timeout", or "retention"

Step 2: Check Basic Syntax

□ Time window specified for event tables?
□ Clauses in correct order?
□ Parentheses balanced in calculations?
□ Field names spelled correctly?

Step 3: Simplify the Query

Start with the minimal query and add complexity one step at a time:

/* Stage 1: Base table only */
execution.events during past 1d
| limit 10

/* Stage 2: Add primary filter */
execution.events during past 1d
| where binary.name = "outlook.exe"
| limit 10

/* Stage 3: Add aggregation (simple) */
execution.events during past 1d
| where binary.name = "outlook.exe"
| summarize count = count()

/* Stage 4: Add calculations (if needed) */
execution.events during past 1d
| where binary.name = "outlook.exe"
| summarize
    avg_memory = real_memory.avg(),
    device_count = device.count()

/* Stage 5: Expand time window */
execution.events during past 7d
| where binary.name = "outlook.exe"
| summarize
    avg_memory = real_memory.avg(),
    device_count = device.count()

Step 4: Validate Data Exists

/* Remove all filters and check if base table has data */
execution.events during past 1d
| limit 5

/* If this returns nothing, no data exists in past day */

Step 5: Check Common Patterns

□ Using count() on events? → Use device.count() instead
□ Referencing variables in same summarize? → Repeat full calculation
□ Using compute after summarize? → Move calculation inside summarize
□ Querying past 2d vs past 48h? → Understand timezone differences
□ Missing by in time-series trend? → Add by 1h or by 1d

Quick Debugging Checklist

Copy this for every query issue:

□ Time window specified for event tables
□ Clauses in correct order (where → with/include → compute → summarize → list → sort → limit)
□ Field names verified in Field Reference
□ Within retention limits (8 days high-res, 30 days low-res)
□ Tested incrementally from simple to complex
□ Used | limit 10 during development
□ Filters not too restrictive (returns some data)
□ No compute after summarize
□ No variable references within same summarize clause

Additional Resources