Geolocation and IP address handling
This article explains how geolocation lookup and IP address handling work in Application Insights, along with how to modify the default behavior.
Default behavior
By default, IP addresses are temporarily collected but not stored in Application Insights. The basic process is as follows:
When telemetry is sent to Azure, Application Insights uses the IP address to do a geolocation lookup by using GeoLite2 from MaxMind. Application Insights uses the results of this lookup to populate the fields client_City, client_StateOrProvince, and client_CountryOrRegion. The address is then discarded, and 0.0.0.0 is written to the client_IP field.
Geolocation data can be removed in the following ways.
Note
Application Insights uses an older version of the GeoLite2 database. If you experience accuracy issues with IP to geolocation mappings, then as a workaround you can disable IP masking and utilize another geomapping service to convert the client_IP field of the underlying telemetry to a more accurate geolocation. We are currently working on an update to improve the geolocation accuracy.
The telemetry types are:
- Browser telemetry: Application Insights collects the sender's IP address. The ingestion endpoint calculates the IP address.
- Server telemetry: The Application Insights telemetry module temporarily collects the client IP address. The IP address isn't collected locally when the
X-Forwarded-Forheader is set. When the incoming list of IP address has more than one item, the last IP address is used to populate geolocation fields.
This behavior is by design to help avoid unnecessary collection of personal data and ip address location information. Whenever possible, we recommend avoiding the collection of personal data.
Note
Although the default is to not collect IP addresses, you can override this behavior. We recommend verifying that the collection doesn't break any compliance requirements or local regulations.
To learn more about handling personal data in Application Insights, consult the guidance for personal data.
While not collecting ip addresses will also not collect city and other geolocation attributes are populated by our pipeline by using the IP address, you can also mask IP collection at the source. This can be done by either removing the client IP initializer Configuration with Applications Insights Configuration, or providing your own custom initializer. For more information, see API Filtering example..
Storage of IP address data
To enable IP collection and storage, the DisableIpMasking property of the Application Insights component must be set to true. You can set this property through Azure Resource Manager templates or by calling the REST API.
Azure Resource Manager template
{
"id": "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/microsoft.insights/components/<resource-name>",
"name": "<resource-name>",
"type": "microsoft.insights/components",
"location": "westcentralus",
"tags": {
},
"kind": "web",
"properties": {
"Application_Type": "web",
"Flow_Type": "Redfield",
"Request_Source": "IbizaAIExtension",
// ...
"DisableIpMasking": true
}
}
Portal
If you only need to modify the behavior for a single Application Insights resource, use the Azure portal.
Go your Application Insights resource, and then select Automation > Export Template.
Select Deploy.

Select Edit Template.

Note
If you experience the following error (as shown in the screenshot), you can resolve it: "The resource group is in a location that is not supported by one or more resources in the template. Please choose a different resource group." Temporarily select a different resource group from the dropdown list and then re-select your original resource group.
In the JSON template locate
propertiesinsideresources, add a comma to the last JSON field, and then add the following new line:"DisableIpMasking": true. Then select Save.
Select Review + create > Create.
Note
If you see "Your deployment failed," look through your deployment details for the one with the type
microsoft.insights/componentsand check the status. If that one succeeds, the changes made toDisableIpMaskingwere deployed.After the deployment is complete, new telemetry data will be recorded.
If you select and edit the template again, you'll see only the default template without the newly added property. If you aren't seeing IP address data and want to confirm that
"DisableIpMasking": trueis set, run the following PowerShell commands:# Replace `Fabrikam-dev` with the appropriate resource and resource group name. # If you aren't using Azure Cloud Shell, you need to connect to your Azure account # Connect-AzAccount $AppInsights = Get-AzResource -Name 'Fabrikam-dev' -ResourceType 'microsoft.insights/components' -ResourceGroupName 'Fabrikam-dev' $AppInsights.PropertiesA list of properties is returned as a result. One of the properties should read
DisableIpMasking: true. If you run the PowerShell commands before deploying the new property with Azure Resource Manager, the property won't exist.
REST API
The REST API payload to make the same modifications is as follows:
PATCH https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/microsoft.insights/components/<resource-name>?api-version=2018-05-01-preview HTTP/1.1
Host: management.azure.com
Authorization: AUTH_TOKEN
Content-Type: application/json
Content-Length: 54
{
"location": "<resource location>",
"kind": "web",
"properties": {
"Application_Type": "web",
"DisableIpMasking": true
}
}
Telemetry initializer
If you need a more flexible alternative than DisableIpMasking, you can use a telemetry initializer to copy all or part of the IP address to a custom field.
ASP.NET or ASP.NET Core
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
namespace MyWebApp
{
public class CloneIPAddress : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
ISupportProperties propTelemetry = telemetry as ISupportProperties;
if (propTelemetry !=null && !propTelemetry.Properties.ContainsKey("client-ip"))
{
string clientIPValue = telemetry.Context.Location.Ip;
propTelemetry.Properties.Add("client-ip", clientIPValue);
}
}
}
}
Note
If you can't access ISupportProperties, make sure you're running the latest stable release of the Application Insights SDK. ISupportProperties is intended for high cardinality values. GlobalProperties is more appropriate for low cardinality values like region name and environment name.
Enable the telemetry initializer for ASP.NET
using Microsoft.ApplicationInsights.Extensibility;
namespace MyWebApp
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
//Enable your telemetry initializer:
TelemetryConfiguration.Active.TelemetryInitializers.Add(new CloneIPAddress());
}
}
}
Enable the telemetry initializer for ASP.NET Core
You can create your telemetry initializer the same way for ASP.NET Core as for ASP.NET. To enable the initializer, use the following example for reference:
using Microsoft.ApplicationInsights.Extensibility;
using CustomInitializer.Telemetry;
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ITelemetryInitializer, CloneIPAddress>();
}
View the results of your telemetry initializer
If you send new traffic to your site and wait a few minutes, you can then run a query to confirm that the collection is working:
requests
| where timestamp > ago(1h)
| project appName, operation_Name, url, resultCode, client_IP, customDimensions.["client-ip"]
Newly collected IP addresses will appear in the customDimensions_client-ip column. The default client-ip column will still have all four octets zeroed out.
If you're testing from localhost, and the value for customDimensions_client-ip is ::1, this value is expected behavior. The ::1 value represents the loopback address in IPv6. It's equivalent to 127.0.0.1 in IPv4.
Next steps
Learn more about personal data collection in Application Insights.
Learn more about how IP address collection in Application Insights works. This article an older external blog post written by one of our engineers. It predates the current default behavior where the IP address is recorded as
0.0.0.0, but it goes into greater depth on the mechanics of the built-in telemetry initializer.
Feedback
Submit and view feedback for