If you want to use a version from the Microsoft registry, they provide the instructions.
This is similar to the other answer where we first clear our installed dotnet packages that are from different sources, but then we tell apt to prefer the dotnet related packages by lowering the preference for the official registry.
Steps are simplified here, reproduced from the link due to community guidelines:
Remove the existing packages: sudo apt remove 'dotnet*' 'aspnet*' 'netstandard*'
If you run dotnet --info
and it still has values for SDKs, Runtimes, etc., purge them. Example: sudo apt remove --purge 'dotnet*' 'aspnet*' 'netstandard*'
Create the preferences file, if it doesn't exist: touch /etc/apt/preferences
Run this command to see what the current apt package sources are, you'll need these in the next step: apt-cache policy '~ndotnet.*' | grep -v microsoft | grep '/ubuntu' | cut -d"/" -f3 | sort -u
Open /etc/apt/preferences
and add the following block to it, once per source returned from the previous step. Replace <your-package-source>
with the source from the previous step. Mine were archive.ubuntu.com
and security.ubuntu.com
, but these can apparently vary by location.
Package: dotnet* aspnet* netstandard*
Pin: origin "<your-package-source>"
Pin-Priority: -10
Save and exit the preferences
file.
Reinstall your dotnet package(s).
I ran
sudo apt install dotnet-sdk-7.0=7.0.306-1
because I wanted the latest version. Ubuntu was on 7.0.109. Run the following to see what versions are available:
apt list -a dotnet-sdk-7.0
The output shows a non-ubuntu package installed, and the lower-versioned ubuntu package midway down the list.

Update 2023-08-29: DNS issues?
From another WSL2 instance on a different system, I tried a restart between removing, and then after installing .NET with no luck. Note that I also tried a purge
(not called out above, but it's in the list, now) with no luck.
My specific issue this time was listed under the OUTPUT
area, normally sharing space with the DEBUG CONSOLE
and TERMINAL
, when ".NET Runtime" was selected in the drop down list. I believe this is used by one of the VS Code C# extensions. Without this working, I couldn't generate build tasks nor launch configs by using the debug play button. (I assume manual dotnet build
commands may have worked, but I didn't test that. I like my F5 key for build/run!) I don't believe Intellisense worked, either.
Before my fix below, the output window would show "Downloading .NET version(s) ........", and it would never complete. After fixing, it resolves with a "Done!" message, as shown below.

This system did not yet have my WSL2 DNS fixes, included below. I'm not sure if this is exactly what fixed the problem, but it fixed it for me: gist for update to wsl.conf
You can get to the original thread, which spans from Windows 10 to current versions of 11, via a comment in the last line of my gist. Or this helpful comment on the original gist seems helpful if you want to configure it from the Windows side. I haven't tested that one.
The ultimate update is to add the following command to /etc/wsl.conf
, which is supported in WSL2 on Windows 11 (maybe newer versions of 10?):
[boot]
command="printf \"nameserver 1.1.1.1\n$(cat /etc/resolv.conf)\nnameserver 8.8.8.8\nnameserver 1.0.0.1\n\" > /etc/resolv.conf"
This injects public DNS nameservers around your local machine's bridge IP (bridge IP comes from /etc/resolv.conf
and is generated when the WSL service starts up or the distro is booted (not sure exactly when, feel free to update the specifics).
The Powershell version does the same, but it takes the configured nameservers from the Windows OS and modifies the resolv.conf, which may be a better option for security with work machines (VPNs and whatnot).