Understanding Azure Data Explorer Ingestion
Azure Data Explorer (ADX) ingests data from various sources — Event Hubs, IoT Hub, Blob Storage, and direct API calls. Ingestion failures occur when source data is malformed, permissions are incorrect, schema mappings don’t match, or queue backlogs build up from excessive ingestion volume. This guide covers diagnosis and resolution of all common ingestion failures.
Understanding the Root Cause
Resolving Azure Data Explorer Ingestion Failures and Queue Backlogs requires more than applying a quick fix to suppress error messages. The underlying cause typically involves a mismatch between your application’s expectations and the service’s actual behavior or limits. Azure services enforce quotas, rate limits, and configuration constraints that are documented but often overlooked during initial development when traffic volumes are low and edge cases are rare.
When this issue appears in production, it usually indicates that the system has crossed a threshold that was not accounted for during capacity planning. This could be a throughput limit, a connection pool ceiling, a timeout boundary, or a resource quota. The error messages from Azure services are designed to be actionable, but they sometimes point to symptoms rather than the root cause. For example, a timeout error might actually be caused by a DNS resolution delay, a TLS handshake failure, or a downstream dependency that is itself throttled.
The resolution strategies in this guide are organized from least invasive to most invasive. Start with configuration adjustments that do not require code changes or redeployment. If those are insufficient, proceed to application-level changes such as retry policies, connection management, and request patterns. Only escalate to architectural changes like partitioning, sharding, or service tier upgrades when the simpler approaches cannot meet your requirements.
Impact Assessment
Before implementing any resolution, assess the blast radius of the current issue. Determine how many users, transactions, or dependent services are affected. Check whether the issue is intermittent or persistent, as this distinction changes the urgency and approach. Intermittent issues often indicate resource contention or throttling near a limit, while persistent failures typically point to misconfiguration or a hard limit being exceeded.
Review your Service Level Objectives (SLOs) to understand the business impact. If your composite SLA depends on this service’s availability, calculate the actual downtime or degradation window. This information is critical for incident prioritization and for justifying the engineering investment required for a permanent fix versus a temporary workaround.
Consider the cascading effects on downstream services and consumers. When Azure Data Explorer Ingestion Failures and Queue Backlogs degrades, every service that depends on it may also experience failures or increased latency. Map out your service dependency graph to understand the full impact scope and prioritize the resolution accordingly.
Types of Ingestion
| Type | Method | Retry | Best For |
|---|---|---|---|
| Queued | Data management service | Automatic | Production workloads, large volumes |
| Streaming | Direct to engine | No automatic retry | Low-latency, small payloads |
| Ingest from query | .set / .append |
No | Data transformation within cluster |
Viewing Ingestion Failures
// Show recent ingestion failures
.show ingestion failures
| where FailedOn > ago(24h)
| project FailedOn, Database, Table, FailureKind, ErrorCode, Details, IngestionSourcePath
| order by FailedOn desc
// Filter by table
.show ingestion failures
| where Table == "MyTable"
| where FailedOn > ago(1h)
// Check failure by operation ID
.show ingestion failures
| where OperationId == "guid-value"
// Show ingestion operations
.show operations
| where Operation == "DataIngestPull"
| where State == "Failed"
| where StartedOn > ago(1h)
Failure Kinds
| FailureKind | Meaning | Action |
|---|---|---|
| Permanent | Data or configuration error — retry won’t help | Fix data format, schema, or permissions |
| Transient | Temporary service issue | Queued ingestion retries automatically |
Schema Mapping Errors
// Create JSON mapping
.create table MyTable ingestion json mapping 'MyMapping'
'['
' {"Column": "Timestamp", "Properties": {"Path": "$.timestamp"}},'
' {"Column": "DeviceId", "Properties": {"Path": "$.deviceId"}},'
' {"Column": "Temperature", "Properties": {"Path": "$.temperature"}},'
' {"Column": "Humidity", "Properties": {"Path": "$.humidity"}}'
']'
// Create CSV mapping
.create table MyTable ingestion csv mapping 'MyCsvMapping'
'['
' {"Column": "Timestamp", "Ordinal": 0},'
' {"Column": "DeviceId", "Ordinal": 1},'
' {"Column": "Temperature", "Ordinal": 2},'
' {"Column": "Humidity", "Ordinal": 3}'
']'
// Show existing mappings
.show table MyTable ingestion mappings
// Update mapping
.alter table MyTable ingestion json mapping 'MyMapping'
'[...]'
Common Mapping Errors
Error: Stream_ClosingQuoteMissing — CSV format error
Fix: Verify CSV encoding, delimiters, and quoting
Error: Schema_MappingMismatch — Column count or type mismatch
Fix: Update mapping to match actual data structure
Error: BadRequest_InvalidBlob — Unsupported format
Fix: Use supported formats: CSV, JSON, Avro, Parquet, ORC, TXT, TSV
Resilience Patterns for Long-Term Prevention
Once you resolve the immediate issue, invest in resilience patterns that prevent recurrence. Azure’s cloud-native services provide building blocks for resilient architectures, but you must deliberately design your application to use them effectively.
Retry with Exponential Backoff: Transient failures are expected in distributed systems. Your application should automatically retry failed operations with increasing delays between attempts. The Azure SDK client libraries implement retry policies by default, but you may need to tune the parameters for your specific workload. Set maximum retry counts to prevent infinite retry loops, and implement jitter (randomized delay) to prevent thundering herd problems when many clients retry simultaneously.
Circuit Breaker Pattern: When a dependency consistently fails, continuing to send requests increases load on an already stressed service and delays recovery. Implement circuit breakers that stop forwarding requests after a configurable failure threshold, wait for a cooldown period, then tentatively send a single test request. If the test succeeds, the circuit closes and normal traffic resumes. If it fails, the circuit remains open. Azure API Management provides a built-in circuit breaker policy for backend services.
Bulkhead Isolation: Separate critical and non-critical workloads into different resource instances, connection pools, or service tiers. If a batch processing job triggers throttling or resource exhaustion, it should not impact the real-time API serving interactive users. Use separate Azure resource instances for workloads with different priority levels and different failure tolerance thresholds.
Queue-Based Load Leveling: When the incoming request rate exceeds what the backend can handle, use a message queue (Azure Service Bus or Azure Queue Storage) to absorb the burst. Workers process messages from the queue at the backend’s sustainable rate. This pattern is particularly effective for resolving throughput-related issues because it decouples the rate at which requests arrive from the rate at which they are processed.
Cache-Aside Pattern: For read-heavy workloads, cache frequently accessed data using Azure Cache for Redis to reduce the load on the primary data store. This is especially effective when the resolution involves reducing request rates to a service with strict throughput limits. Even a short cache TTL of 30 to 60 seconds can dramatically reduce the number of requests that reach the backend during traffic spikes.
Permission Errors
Error: Download_Forbidden — Access denied to source storage
# Grant ADX managed identity access to storage
az role assignment create \
--assignee $(az kusto cluster show --name myCluster --resource-group myRG --query identity.principalId -o tsv) \
--role "Storage Blob Data Reader" \
--scope $(az storage account show --name myStorage --resource-group myRG --query id -o tsv)
# Verify SAS token is valid and has read permission
# Required permissions: Read (r) and List (l)
Event Hub Data Connection Issues
# Create Event Hub data connection
az kusto data-connection event-hub create \
--cluster-name myCluster \
--database-name myDB \
--data-connection-name myConnection \
--resource-group myRG \
--event-hub-resource-id /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.EventHub/namespaces/{ns}/eventhubs/{eh} \
--consumer-group '$Default' \
--table-name MyTable \
--mapping-rule-name MyMapping \
--data-format JSON
# Check data connection status
az kusto data-connection show \
--cluster-name myCluster \
--database-name myDB \
--data-connection-name myConnection \
--resource-group myRG
Queue Backlogs
// Check ingestion utilization
.show capacity
| where Resource == "Ingestions"
// Check batching policy
.show table MyTable policy ingestionbatching
// Adjust batching for faster ingestion
.alter table MyTable policy ingestionbatching
```
{
"MaximumBatchingTimeSpan": "00:00:30",
"MaximumNumberOfItems": 500,
"MaximumRawDataSizeMB": 100
}
```
// For large ingestion, use async with distributed flag
.set async MyTable with (distributed=true) <|
SourceTable
| where Timestamp > ago(1h)
Ingestion Best Practices
- Keep ingestion operations under 1 GB — use multiple commands for larger datasets
- Use distributed=true for datasets exceeding 1 GB to parallelize across nodes
- Use queued ingestion for production — it provides automatic retries for transient failures
- Minimize concurrent ingestion commands — they are resource-intensive
- Use
ingestIfNotExiststo prevent duplicate ingestion - Validate data format and schema mapping before bulk ingestion
- Monitor FailureKind — Permanent failures need data/config fixes; Transient are auto-retried
- Set appropriate batching policies to balance latency and throughput
Monitoring
# Check ingestion metrics
az monitor metrics list \
--resource $(az kusto cluster show --name myCluster --resource-group myRG --query id -o tsv) \
--metric "IngestionResult" "IngestionLatencyInSeconds" \
--interval PT5M
# Enable diagnostic logs
az monitor diagnostic-settings create \
--name myDiag \
--resource $(az kusto cluster show --name myCluster --resource-group myRG --query id -o tsv) \
--workspace myLogAnalytics \
--logs '[{"category": "IngestionLogs", "enabled": true}]'
Capacity Planning and Forecasting
The most effective resolution is preventing the issue from recurring through proactive capacity planning. Establish a regular review cadence where you analyze growth trends in your service utilization metrics and project when you will approach limits.
Use Azure Monitor metrics to track the key capacity indicators for Azure Data Explorer Ingestion Failures and Queue Backlogs over time. Create a capacity planning workbook that shows current utilization as a percentage of your provisioned limits, the growth rate over the past 30, 60, and 90 days, and projected dates when you will reach 80 percent and 100 percent of capacity. Share this workbook with your engineering leadership to support proactive scaling decisions.
Factor in planned events that will drive usage spikes. Product launches, marketing campaigns, seasonal traffic patterns, and batch processing schedules all create predictable demand increases that should be accounted for in your capacity plan. If your application serves a global audience, consider time-zone-based traffic distribution and scale accordingly.
Implement autoscaling where the service supports it. Azure autoscale rules can automatically adjust capacity based on real-time metrics. Configure scale-out rules that trigger before you reach limits (at 70 percent utilization) and scale-in rules that safely reduce capacity during low-traffic periods to optimize costs. Test your autoscale rules under load to verify that they respond quickly enough to protect against sudden traffic spikes.
Summary
ADX ingestion failures primarily stem from schema mapping mismatches (column order, types, or JSON paths not matching source data), permission errors on source storage (expired SAS tokens or missing RBAC roles), and malformed source data (bad CSV quoting, invalid JSON). Check .show ingestion failures for detailed error information, distinguish between Permanent (needs fix) and Transient (auto-retried) failures, and keep ingestion operations under 1 GB with the distributed=true flag for larger datasets.
For more details, refer to the official documentation: What is Azure Data Explorer?, Azure Data Explorer data ingestion overview, Kusto Query Language overview.