The .NET SDK includes a telemetry feature that collects usage data and sends it to Microsoft when you use .NET CLI commands. This data collection includes information about exceptions if the .NET CLI crashes. The .NET CLI, which comes with the .NET SDK, is a set of commands that allows you to build, test, and publish your .NET applications. Telemetry data helps the .NET team understand how these tools are used, enabling them to improve the developer experience. Crash information is particularly valuable, assisting the team in diagnosing problems and fixing bugs.
The data collected is published in aggregate under the Creative Commons Attribution License. Some of the collected data is publicly available at .NET CLI Telemetry Data.
Scope of Telemetry Collection
The dotnet
command serves two main purposes: running applications and executing CLI commands. Telemetry is not collected when you use dotnet
to start applications in the following format:
dotnet [path-to-app].dll
Telemetry is collected when you use any of the .NET CLI commands, such as:
dotnet build
dotnet pack
dotnet run
How to Opt-Out of .NET CLI Telemetry
The .NET SDK telemetry feature is enabled by default in Microsoft distributions of the SDK. To opt out of this telemetry collection, you need to set the environment variable DOTNET_CLI_TELEMETRY_OPTOUT
to 1
or true
.
A single telemetry event is also sent by the .NET SDK installer upon successful installation. To opt out of this installer telemetry, set the DOTNET_CLI_TELEMETRY_OPTOUT
environment variable before you install the .NET SDK.
Important: To opt out after you have already started the installer, you must close the installer, set the environment variable, and then run the installer again with the variable set.
Telemetry Disclosure
The .NET SDK displays a message similar to the following the first time you run one of the .NET CLI commands (for example, dotnet build
). The exact text might vary slightly depending on the SDK version you are using. This “first-time use” experience is how Microsoft informs you about data collection:
Telemetry --------- The .NET tools collect usage data in order to help us improve your experience. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell. Read more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry
To suppress this message and the .NET welcome message, set the environment variable DOTNET_NOLOGO
to true
. Note that this variable only affects the messages and does not impact the telemetry opt-out setting.
Data Points Collected by .NET CLI Telemetry
Protecting your privacy is a priority for us. The telemetry feature does not collect personal data such as usernames or email addresses. It does not scan your code or extract project-level data like names, repositories, or authors. It also does not extract the contents of any data files accessed or created by your applications, memory dumps of your application objects, or clipboard content. Data is securely transmitted to Microsoft servers using Azure Monitor technology, stored under restricted access, and published under strict security controls within secure Azure Storage systems.
If you suspect that telemetry is collecting sensitive data or data that is handled insecurely or inappropriately, please raise an issue in the dotnet/sdk repository or send an email to for investigation.
The telemetry feature collects the following data points:
SDK Version | Data Collected |
---|---|
All | Invocation timestamp. |
All | Invoked command (e.g., “build”), hashed starting from 2.1. |
All | Truncated IP address (three octets) used to determine geographic location. |
All | Operating system and version. |
All | Runtime ID (RID) where the SDK is running. |
All | .NET SDK version. |
All | Telemetry profile: an optional value used only with explicit user opt-in and used internally at Microsoft. |
>=2.0 | Command arguments and options: certain arguments and options are collected (not arbitrary strings). See collected options. Hashed after 2.1.300. |
>=2.0 | Whether the SDK is running in a container. |
>=2.0 | Target framework (from TargetFramework event), hashed starting from version 2.1. |
>=2.0 | Hashed Media Access Control (MAC) address (SHA256). |
>=2.0 | Current working directory hashed. |
>=2.0 | Installation success report, with hashed installer exe filename. |
>=2.1.300 | Kernel version. |
>=2.1.300 | Libc version/release. |
>=3.0.100 | Whether output is redirected (true or false). |
>=3.0.100 | On CLI/SDK crash, exception type and stack trace (only CLI/SDK code is included in the stack trace sent). For more information, see Crash exception telemetry. |
>=5.0.100 | Hashed TargetFrameworkVersion used for the build (MSBuild property) |
>=5.0.100 | Hashed RuntimeIdentifier used for the build process (MSBuild property) |
>=5.0.100 | Hashed SelfContained used for compilation (MSBuild property) |
>=5.0.100 | Hashed UseApphost used for build (MSBuild property) |
>=5.0.100 | Hashed OutputType used for build (MSBuild property) |
>=5.0.201 | Hashed PublishReadyToRun used for build (MSBuild property) |
>=5.0.201 | Hashed PublishTrimmed used for build (MSBuild property) |
>=5.0.201 | Hashed PublishSingleFile used in the build process (MSBuild property) |
>=5.0.202 | Elapsed time from process start to entering the CLI program’s main method, measuring host and runtime startup time. |
>=5.0.202 | Elapsed time for the step that adds .NET Tools to the path on first execution. |
>=5.0.202 | Elapsed time to display the first-time usage notification on first execution. |
>=5.0.202 | Elapsed time for ASP.NET Certificate creation on first run. |
>=5.0.202 | Time taken to parse CLI input. |
>=6.0.100 | Operating System Architecture |
>=6.0.104 | Hashed PublishReadyToRunUseCrossgen2 used for build (MSBuild property) |
>=6.0.104 | Hashed Crossgen2Pack Version used for build (MSBuild property) |
>=6.0.104 | “Hashed CompileListCount” used for build (MSBuild property) |
>=6.0.104 | Hashed _ReadyToRunCompilationFailures used in the build process (MSBuild property) |
>=6.0.300 | Whether the CLI is invoked from a Continuous Integration environment. For more information, see Continuous Integration Detection. |
>=7.0.100 | MSBuild property ‘Hashed PublishAot’ used for build |
>=7.0.100 | Hashed Publish Protocol used for build (MSBuild property) |
>=8.0.100 | Hashed TargetPlatformIdentifier used for build (MSBuild property) |
>=8.0.100 | Hashed HybridGlobalization used for build (property in MSBuild) |
>=8.0.100 | Whether the .NET Blazor WebAssembly SDK is used. |
>=8.0.100 | Whether the .NET WebAssembly SDK is used. |
>=8.0.100 | Whether .NET MAUI is used. |
>=8.0.100 | Whether the .NET mobile SDK is used. |
>=8.0.100 | Whether other mobile SDKs are used (like: Avalonia, Uno). |
>=8.0.100 | Whether Mono AOT is used. |
>=8.0.100 | Whether IL strip feature on Mono AOT framework is used? |
>=8.0.100 | Whether Mono interpreter is used. |
>=8.0.100 | Whether library mode for mobile is used. |
>=8.0.100 | Whether NativeAOT is used. |
>=8.0.100 | Mono runtime package version used. |
Collected Options and Arguments
Certain commands send additional data. A subset of commands sends the first argument:
Command | First Argument Data Sent |
---|---|
dotnet help |
Help command being looked up. |
dotnet new |
Template name (protected by hashing). |
dotnet add |
The word package or reference . |
dotnet remove |
The word package or reference . |
dotnet list |
The word package or reference . |
dotnet sln |
The word add , list , or remove . |
dotnet nuget |
The word delete , locals , or push . |
dotnet workload |
The words install , update , list , search , uninstall , repair , restore and workload name (hashed). |
dotnet tool |
The words install , update , list , search , uninstall , run and dotnet tool name (hashed). |
A subset of commands sends selected options if they are used, along with their values:
Option | Commands |
---|---|
--verbosity |
All commands |
--language |
dotnet new |
--configuration |
dotnet build , dotnet clean , dotnet publish , dotnet run , dotnet test |
--framework |
dotnet build , dotnet clean , dotnet publish , dotnet run , dotnet test , dotnet vstest |
--runtime |
dotnet build , dotnet publish |
--platform |
dotnet vstest |
--logger |
dotnet vstest |
--sdk-package-version |
dotnet migrate |
When the SDK fails to execute a built-in command, any command resolver that successfully resolves the command sends the hashed name of the command along with the type name of the command resolver.
Except for --verbosity
and --sdk-package-version
, all other values are hashed starting with the .NET Core 2.1.100 SDK.
Telemetry for Template Instantiation
The dotnet new
template instantiation command collects additional data for Microsoft-authored templates, starting with .NET Core 2.1.100 SDK:
--framework
--auth
Crash Exception Telemetry in .NET CLI
If the .NET CLI/SDK experiences a crash, it collects the exception name and stack trace from the CLI/SDK code. This information is gathered to help assess issues and improve the quality of the .NET SDK and CLI. This section provides details about the data collected and offers guidance for users building their own versions of the .NET SDK to avoid unintentional disclosure of personal or sensitive information.
The .NET CLI only collects information for CLI/SDK exceptions, not exceptions within your applications. The data collected includes the exception name and the stack trace, which originates from the CLI/SDK code.
The following example illustrates the type of data collected during a crash:
System.IO.IOException at System.ConsolePal.WindowsConsoleStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) at System.IO.StreamWriter.Write(Char[] buffer) at System.IO.TextWriter.WriteLine() at System.IO.TextWriter.SyncTextWriter.WriteLine() at Microsoft.DotNet.Cli.Utils.Reporter.WriteLine() at Microsoft.DotNet.Tools.Run.RunCommand.EnsureProjectIsBuilt() at Microsoft.DotNet.Tools.Run.RunCommand.Execute() at Microsoft.DotNet.Tools.Run.RunCommand.Run(String[] args) at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient) at Microsoft.DotNet.Cli.Program.Main(String[] args)
Continuous Integration Detection
To detect if the .NET CLI is running within a Continuous Integration environment, the .NET CLI checks for the presence and values of several well-known environment variables set by common CI providers.
The complete list of environment variables and how their values are handled is shown below. Note that in each case, the value of the environment variable is never collected, only used to set a boolean flag.
Variable | Provider | Action |
---|---|---|
TF_BUILD | Azure Pipelines | Parses boolean value |
GITHUB_ACTIONS | GitHub Actions | Parses boolean value |
APPVEYOR | Appveyor | Parses boolean value |
CI | Many/Most | Parses boolean value |
TRAVIS | Travis CI | Parses boolean value |
CIRCLECI | Circle CI | Parses boolean value |
CODEBUILD_BUILD_ID, AWS_REGION | Amazon Web Services CodeBuild | Checks if all present and non-empty |
BUILD_ID, BUILD_URL | Jenkins | Checks if all present and non-empty |
BUILD_ID, PROJECT_ID | Google Cloud Build | Checks if all present and non-empty |
TEAMCITY_VERSION | TeamCity | Checks if present and non-null |
JB_SPACE_API_URL | JetBrains Space | Checks if present and non-null |
Preventing Unintentional Information Disclosure
.NET contributors and anyone running self-built versions of the .NET SDK should be mindful of the path to their SDK source code. If a crash occurs while using a .NET SDK that is a custom debug build or configured with custom build symbol files, the SDK source file paths from the build machine are collected as part of the stack trace and are not hashed.
Therefore, custom builds of the .NET SDK should not be located in directories where the path names expose personal or sensitive information.