No data in Application Insights? SDK self-diagnostics and a checklist
When Application Insights shows nothing, find out which side is failing before changing code: send one test record from the app's host with PowerShell or curl, and if it arrives, the problem is in the app's SDK or configuration; if it doesn't, it's the network, the endpoint or the resource. Then turn on the SDK's own log: FileDiagnosticsTelemetryModule in the classic 2.x SDK, ApplicationInsightsDiagnostics.json in SDK 3.x, OpenTelemetry's self-diagnostics for the Microsoft OpenTelemetry Distro, and selfDiagnostics in the Java agent.
“No data” has two very different causes: telemetry that is never sent, and telemetry that is sent and then lost or dropped. Microsoft’s troubleshooting guide is built around separating the two, and so is this checklist.
The checklist, in order
- Right resource. Compare the connection string the app actually uses with the one on the resource’s Overview page. A connection string set in code wins over
APPLICATIONINSIGHTS_CONNECTION_STRINGin the classic ASP.NET Core SDK, so a hard-coded test value can hide a correct environment variable. See setting the connection string. - Right place and time. Query Logs directly for the last 30 minutes. Remember that KQL timestamps are UTC.
- The network. Send one test record from the app’s host (below). Apps configured with a connection string send to the regional endpoint in it,
https://<region>.in.applicationinsights.azure.com; apps configured with an instrumentation key alone use the globalhttps://dc.applicationinsights.azure.com, and Microsoft ended support for instrumentation-key ingestion on March 31, 2025. - Authentication. If the resource requires Microsoft Entra ID, an app that sends with the connection string alone is rejected, and nothing appears even though instrumentation looks right.
- Intentional drops. Sampling, telemetry processors or span processors that filter,
ILoggerlevels (see logging), the daily cap and ingestion sampling all remove data by design. The sampling guide shows how to see the retained percentage. - Development settings.
DisableTelemetry, a missing connection string in the Distro, or a console exporter left in place all stop export. See disabling in development. - Shutdown. Short-lived processes lose whatever is still buffered unless they flush. See desktop and console apps.
Test the pipeline with one record
Microsoft recommends sending an availability result as the test record, because the ingestion pipeline never samples availability results out. The one-request guide explains the payload; this is the short form.
Send one availability result with curl, using the IngestionEndpoint and instrumentation key from your connection string:
curl -s -H "Content-Type: application/json" -X POST \
"https://<region>.in.applicationinsights.azure.com/v2/track" \
-d '{"ver":1,"name":"Microsoft.ApplicationInsights.Metric","time":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","sampleRate":100,"iKey":"<instrumentation key>","flags":0,
"data":{"baseType":"AvailabilityData","baseData":{"ver":2,"id":"probe-1","name":"Pipeline probe","duration":"00.00:00:01","success":true,"runLocation":"my-host","message":"test"}}}'
A healthy response is HTTP 200 with itemsReceived equal to itemsAccepted. Then look for the row in availabilityResults. If it’s there, DNS, the network, the endpoint, the workspace and the portal all work, and the problem is in the app. If the call fails, Microsoft lists the usual client-side culprits: DNS that resolves the endpoint wrongly (often a second Azure Monitor Private Link scope overriding DNS), a firewall or gateway blocking TCP, or an app that uses TLS 1.0 or 1.1 where the endpoint requires TLS 1.2. On a resource that only accepts Microsoft Entra ID, v2/track answers 400; a 401 means the SDK couldn’t get a token; a 403 means the identity lacks the Monitoring Metrics Publisher role.
Classic SDK 2.x
Microsoft’s first suggestion for 2.x is to run the app under the Visual Studio debugger and check that telemetry events appear in the Output window, which proves collection works before the network is involved. The SDK also reports its own errors (a missing performance counter, an initializer that throws) as trace telemetry through DiagnosticsTelemetryModule, so search traces for messages from the SDK.
For a full internal log, add FileDiagnosticsTelemetryModule. On .NET Framework it goes in ApplicationInsights.config:
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.FileDiagnosticsTelemetryModule, Microsoft.ApplicationInsights">
<Severity>Verbose</Severity>
<LogFileName>mylog.txt</LogFileName>
<LogFilePath>C:\\SDKLOGS</LogFilePath>
</Add>
</TelemetryModules>
In ASP.NET Core 2.x, register the same module in code:
builder.Services.AddSingleton<ITelemetryModule, FileDiagnosticsTelemetryModule>();
builder.Services.ConfigureTelemetryModule<FileDiagnosticsTelemetryModule>((module, options) =>
{
module.LogFilePath = @"C:\SDKLOGS";
module.LogFileName = "mylog.txt";
module.Severity = "Verbose";
});
The process needs write access to the folder and a restart to pick it up; revert it when you’re done. Without changing the app, you can capture the same events with PerfView or dotnet-trace by listening to the SDK’s EventSource providers, whose names start with Microsoft-ApplicationInsights- (and Redfield-Microsoft-ApplicationInsights- for the IIS agent).
Microsoft’s .NET page adds a few 2.x specifics worth checking: all Microsoft.ApplicationInsights DLLs deployed to the server, a <defaultProxy> in web.config when the server must use a proxy, and correctly named types in <TelemetryInitializers> and <TelemetryProcessors>, because one wrong type name can stop the SDK sending anything.
Today: SDK 3.x and the Microsoft OpenTelemetry Distro
SDK 3.x
SDK 3.x has its own self-diagnostics, switched on by a file named ApplicationInsightsDiagnostics.json. The SDK looks for it in the current working directory, then in AppContext.BaseDirectory, rereads it every 10 seconds, and stops logging when you delete it, so no restart is needed.
ApplicationInsightsDiagnostics.json, placed next to the app:
{
"LogDirectory": ".",
"FileSize": 1024,
"LogLevel": "Error"
}
FileSize is in KiB, between 1 MiB and 128 MiB, and the file is overwritten in a circle. LogLevel takes an EventLevel name (Critical, Error, Warning, Informational, Verbose). If any field can’t be parsed, the whole file is ignored. SDK 3.x also refuses to start without a connection string, which turns a silent “no data” into a visible error.
The Microsoft OpenTelemetry Distro for .NET
The Distro sits on the OpenTelemetry .NET SDK, and everything shipped from that repository, the Azure Monitor exporter’s OpenTelemetry-AzureMonitor-Exporter source included, reports internal problems through EventSources whose names start with OpenTelemetry-. OpenTelemetry’s self-diagnostics writes them to a file. Microsoft.OpenTelemetry 1.2.0 depends on OpenTelemetry 1.19.1, which uses the file-based switch: drop OTEL_DIAGNOSTICS.json into the working directory.
OTEL_DIAGNOSTICS.json for OpenTelemetry .NET 1.19 and earlier:
{
"LogDirectory": ".",
"FileSize": 32768,
"LogLevel": "Warning",
"FormatMessage": "true"
}
OpenTelemetry .NET 1.20.0 added a newer mechanism configured by environment variables, and marks the JSON file as superseded (it still works). If your app resolves OpenTelemetry 1.20 or later, set the variables before the process starts:
export OTEL_DOTNET_SELF_DIAGNOSTICS_LOG_DIRECTORY=./otel-logs
export OTEL_LOG_LEVEL=debug # default is Warning
Don’t configure both, or you get every event twice. To see what the app emits without involving the network at all, add ExportTarget.Console next to ExportTarget.AzureMonitor while you debug.
Node.js, Python and Java
Node.js reads APPLICATIONINSIGHTS_INSTRUMENTATION_LOGGING_LEVEL (NONE to ALL), APPLICATIONINSIGHTS_LOG_DESTINATION (file or file+console) and APPLICATIONINSIGHTS_LOGDIR; by default the file is applicationinsights.log in the temp folder.
Python logs exporter problems through the standard logging library at WARNING or ERROR, and the library’s default level hides the rest, so raise it:
import logging
logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s", level=logging.DEBUG)
Microsoft’s Python page also covers two classics: requests missing in FastAPI or Flask because the framework was imported before the distro was configured, and duplicate telemetry from configuring the exporter more than once.
Java 3.x already logs at INFO to applicationinsights.log (next to the agent jar) and the console. Raise the level with APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_LEVEL (OFF through TRACE) and move the file with APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH.
Find out what did arrive
Once something arrives, check which roles and instances are sending:
union *
| where timestamp > ago(1h)
| summarize items = count() by itemType, cloud_RoleName, cloud_RoleInstance
| order by items desc
If data stopped abruptly at the same time every day, the daily cap is the suspect. In a workspace-based resource, this finds the cap events:
_LogOperation
| where Category =~ "Ingestion"
| where Detail contains "OverQuota"
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Test record fails from the server, works from a laptop | Firewall, proxy or DNS | Allow HTTPS to the regional endpoint; check Private Link DNS |
| Test record arrives, app data doesn’t | SDK configuration | Turn on self-diagnostics; compare connection strings |
| HTTP 400 “Authentication not supported” | Resource accepts Microsoft Entra ID only | Configure Entra authentication in the SDK |
| Some telemetry types missing | Sampling, filters or log levels | Check itemCount; review processors and ILogger levels |
| Data stops at the same hour each day | Daily cap | Raise the cap or sample harder |
| Requests missing in a Python web app | Framework imported before the distro | Configure the distro first |
| Nothing from a scheduled job | Process exits before flushing | Flush or dispose the SDK at the end |
| SDK 3.x app won’t start | No connection string | Set APPLICATIONINSIGHTS_CONNECTION_STRING |
Queries for this topic
-
Requests per day by cloud role
requests usage
Returns: One column per day for the last 14 complete days (UTC), split by cloud role name, showing each service's sampling-adjusted request count.
-
Telemetry volume by table, in GB per day
requestsdependenciesexceptionstracescustomEventspageViewsavailabilityResultsperformanceCounterscustomMetricsbrowserTimings cost
Returns: One row per table with the billed gigabytes over the last 7 complete days, the stored rows, the items they stand for after sampling, and the average gigabytes per day, largest first.
Frequently asked questions
How long does it take for telemetry to appear?
Microsoft's .NET troubleshooting page notes that Search usually shows new data first, before the charts, and refreshes on its own. If a test record sent with curl shows up in Logs but your app's data doesn't after a few minutes, stop waiting and turn on the SDK's self-diagnostics.
Can I test Application Insights locally?
Yes. Point a development build at a separate resource, or export to the console: the Distro's ExportTarget.Console and the OpenTelemetry console exporter print every span, log and metric without sending anything. Self-diagnostics works locally too.
Why does my app log nothing to the traces table?
In the classic 2.x SDK the ILogger provider captures Warning and above by default, so Information logs are dropped unless you lower its level. With OpenTelemetry, the app's own logging configuration decides. Also check sampling, trace-based log sampling and any log filter.
Is self-diagnostics safe to leave on in production?
At Warning or Error, yes: OpenTelemetry .NET defaults to Warning for that reason, and the files are size-capped. At Verbose or Debug the output grows quickly and can contain sensitive details, so raise the level only while investigating and lower it afterwards.
Sources, checked
- Troubleshoot missing application telemetry in Azure Monitor Application Insights
- Troubleshoot no data in Application Insights for .NET
- Troubleshooting, self-diagnostics in Application Insights .NET SDK 3.x (GitHub)
- Troubleshooting OpenTelemetry .NET, self-diagnostics (GitHub)
- OpenTelemetry .NET SDK changelog (1.20.0 self-diagnostics)
- Microsoft.OpenTelemetry 1.2.0 (NuGet, dependencies)
- Troubleshoot OpenTelemetry issues in Python
- Configuration options for Application Insights for Java (self-diagnostics)