To install .NET on Ubuntu 26.04 or 24.04, use APT to install dotnet-sdk-10.0 from Ubuntu’s official repositories. The SDK includes the C# compiler, project tools and runtime, so you can create and run C# applications without installing a separate compiler.
.NET is the platform; C# is one of its programming languages. Start with .NET 10 LTS, then create a console app, add a NuGet package and publish the result. There is also an optional .NET 11 route. If a step fails, leave a comment with the error or contact us.
Before you begin
Use Ubuntu 26.04 LTS or 24.04 LTS Desktop or Server, internet access and an account with sudo access. On Ubuntu Desktop, open Terminal with Ctrl+Alt+T.
Keep your release’s normal updates and security repositories enabled. Package availability depends on your architecture and enabled sources; check the candidate if installation fails.
Use sudo for APT only. Create projects, restore packages and run code as your normal user.
If .NET is already installed, identify its source before adding another installation. This guide uses Canonical’s APT packages.
The examples use Bash and a new practice directory under your home folder. No editor, Microsoft account or paid IDE is required.
Step 1: Check the Ubuntu release and existing command
Read the release and look for existing .NET installations:
Ubuntu terminal
cat /etc/os-release
dpkg --print-architecture
type -a dotnet
Expect Ubuntu 26.04 or 24.04. A missing dotnet command is normal before installation. If it exists, run dotnet --list-sdks and check whether it came from APT, Snap or a manual installation. Avoid adding a second route just to fix a PATH problem.
The && runs installation only after the package-list update succeeds; -y accepts APT’s confirmation automatically. The SDK pulls in its matching runtimes and dependencies. You do not need the runtime-only packages as an extra step.
The package is listed in the official Ubuntu archives for 26.04 (resolute) and 24.04 (noble). APT supplies the current packaged patch in the 10.0 series, so your exact SDK version may differ from other tutorials.
Do not add the Microsoft APT feed for .NET
Starting with Ubuntu 24.04 and continuing in 26.04, Microsoft no longer publishes .NET packages for these releases to its APT repository. Canonical maintains .NET in Ubuntu’s feeds. Do not install packages-microsoft-prod.deb for this guide.
Do not mix Ubuntu and Microsoft .NET packages: different layouts and dependencies can cause missing runtime or host errors. A Microsoft repository may still be needed for another product; do not remove it blindly. See Microsoft’s Ubuntu packaging guidance.
The SDK list should include a 10.0.xxx entry. The runtime list should include Microsoft.NETCore.App and Microsoft.AspNetCore.App 10.0.x. The SDK and runtime patch numbers use different formats; they do not need to match. dotnet --version reports the SDK selected in your current directory.
Which .NET version should you use?
As of November 2026, Microsoft’s two actively supported modern .NET releases are .NET 10 LTS and .NET 11 STS. Both are supported through November 14, 2028, provided you keep up with servicing updates. .NET 11 includes C# 15. This guide uses .NET 10 as the default.
.NET 8 and .NET 9 reached Microsoft End of Support on November 10, 2026. An old tutorial or an available package is not a reason to choose them for a new project. Canonical’s support policy for its Ubuntu builds is separate from Microsoft’s upstream lifecycle. Check the .NET support policy when maintaining an existing application.
2. Install only a runtime on a server
Skip this section if you installed the SDK. For a server that only runs an existing ASP.NET Core web application, install the matching runtime instead:
These are alternatives, not three required installations. A runtime cannot create or build projects. Match the major runtime version required by the application; installing .NET 10 does not automatically migrate an app targeting .NET 8. Installing a runtime also does not configure a web service, reverse proxy or firewall.
3. Create and run a C# console app
Step 1: Create an empty practice folder
Use a unique folder so an existing HelloApp project is left alone:
Ubuntu terminal
dotnet_demo_dir=$(mktemp -d "$HOME/dotnet-demo.XXXXXX") &&
cd "$dotnet_demo_dir"
Keep this terminal open. pwd shows the folder’s actual name. The examples below assume you are working here and have the .NET 10 SDK selected.
Step 2: Create the project
Generate the console template, enter its directory and run it:
Ubuntu terminal
dotnet new console -o HelloApp
cd HelloApp
dotnet run
Expect Hello, World!. The template creates HelloApp.csproj (project settings) and Program.cs (your source). It normally restores dependencies automatically. With only the .NET 10 SDK installed, the project targets net10.0; see the side-by-side section if you also installed .NET 11.
Step 3: Change the greeting
While inside HelloApp, replace only this practice project’s Program.cs with:
Ubuntu terminal
cat > Program.cs <<'CS'
Console.WriteLine("Hello from C# on Ubuntu!");
CS
dotnet run
This overwrites the template’s greeting. Do not paste it into an existing project with source you need to keep. Console.WriteLine prints one line; modern C# allows this short form without writing a Main method yourself.
Hello from C# on Ubuntu!
You can edit Program.cs with any text editor. The terminal commands work independently of an IDE.
4. Add and use a NuGet package
Step 1: Add Newtonsoft.Json
From inside HelloApp, add the JSON library:
Ubuntu terminal
dotnet add package Newtonsoft.Json
NuGet downloads the package and records its resolved version in the project file. dotnet package add Newtonsoft.Json is the newer noun-first form in .NET 10; the command above also works. Choose packages you trust: adding one changes your project’s dependencies. See the package command reference.
Step 2: Use the library in Program.cs
Replace the practice file again, then run it:
Ubuntu terminal
cat > Program.cs <<'CS'
using Newtonsoft.Json;
var message = new { Greeting = "Hello", Platform = "Ubuntu" };
string json = JsonConvert.SerializeObject(message);
Console.WriteLine(json);
CS
dotnet run
The anonymous object holds two values. JsonConvert.SerializeObject converts them into JSON text, which the program prints:
{"Greeting":"Hello","Platform":"Ubuntu"}
This example demonstrates a third-party dependency. .NET also includes System.Text.Json, so you do not need Newtonsoft.Json for every JSON task. The Json.NET documentation explains its serialization methods.
5. Build and publish the application
Step 1: Build the project
From the HelloApp directory:
Ubuntu terminal
dotnet build
A successful build reports zero errors. Build compiles your project and restores dependencies when needed; it does not launch the program. Read any warnings rather than assuming success means the code has no problems.
Step 2: Publish a Release build
Prepare the application files for deployment:
Ubuntu terminal
dotnet publish -c Release
For the .NET 10 project above, the default publish directory is bin/Release/net10.0/publish/. The command prints the actual output path. Repeating it updates generated files. This normal framework-dependent publish still needs the matching runtime on the destination machine.
Step 3: Run the published copy
For the net10.0 example, run:
Ubuntu terminal
dotnet bin/Release/net10.0/publish/HelloApp.dll
Expect the same JSON output. Keep the whole publish directory when copying this app, including its dependency and runtime configuration files. A project targeting another framework has a different directory name. dotnet publish -c Release does not automatically produce one self-contained executable; see the publish reference for deployment options.
6. Optional: install .NET 11 side by side
Use .NET 11 STS when a project needs its SDK or C# 15. Canonical provides it through ppa:dotnet/backports on Ubuntu 26.04 and 24.04. This is an additional Canonical-maintained feed; it is not required for the .NET 10 installation above.
Backports support differs from the Ubuntu archive
Canonical describes these PPA packages as best-effort support and not intended for production use. Use this optional route for development and testing. Microsoft’s upstream .NET 11 support dates do not change Canonical’s support terms for these packages.
Step 1: Add Canonical’s backports PPA
This adds a repository and can affect package candidates for later updates. Review the repository information before accepting:
software-properties-common provides add-apt-repository. Confirm a candidate exists for your release and architecture, from the dotnet/backports PPA. Do not add a repository for a different Ubuntu release if it is missing.
The list should now include both 10.0 and 11.0 SDKs. Canonical’s .NET 11 announcement describes its Ubuntu packaging. Prefer this APT route when your existing installation also uses APT.
Choose the SDK for each project
Without a global.json selection, the CLI normally chooses the highest installed SDK. After adding .NET 11, a plain dotnet new console can therefore create a net11.0 project. To use the .NET 10 SDK, select it explicitly before creating the project.
Ubuntu terminal
dotnet --list-sdks
In your practice root, create a global.json file with the following content. Replace 10.0.100 with the complete installed 10.0 SDK version shown above. Do not overwrite an existing global.json without reviewing its purpose:
Save this as global.json using your editor, not as a terminal command. Run dotnet --version from that directory to verify selection. The file applies to its directory and descendants. latestPatch stays within the selected SDK feature band; review the pin when moving to another band. Choosing an SDK is separate from changing a project’s TargetFramework. See .NET version selection.
Microsoft also offers dotnet-install.sh with --channel 11.0 for a user-owned installation, commonly used in CI. It needs manual dependency, PATH and update management. Keep that installation separate from APT; a user-owned dotnet host does not automatically discover SDKs under the APT installation root.
7. Optional: run a single C# file
.NET 10 and later support file-based apps without a .csproj file. Keep these outside HelloApp, because a project can otherwise pick up the extra .cs file and report duplicate top-level statements.
Create a separate script folder
This changes into a new directory outside the project:
Ubuntu terminal
dotnet_script_dir=$(mktemp -d "$HOME/dotnet-script.XXXXXX") &&
cd "$dotnet_script_dir" &&
cat > hello.cs <<'CS'
Console.WriteLine("Hello from a single C# file!");
CS
dotnet run hello.cs
Expect Hello from a single C# file!. You still need the SDK. dotnet run --file hello.cs explicitly selects file mode when you need to avoid ambiguity. These are file-based C# apps, not shell scripts.
8. Fix common .NET problems
Issue 1: Unable to locate dotnet-sdk-10.0
Check the release and configured package candidate:
On 24.04 and 26.04, keep the normal release, updates and security sources enabled. Resolve update or mirror errors first. If the architecture has no candidate, follow Canonical’s supported packaging options; do not install DEBs from another Ubuntu release.
Issue 2: dotnet exists, but no SDK is found
A runtime-only installation cannot build projects. Check the selected command and the SDK list:
Ubuntu terminal
type -a dotnet
dotnet --info
dotnet --list-sdks
Install dotnet-sdk-10.0 if you only installed a runtime. If APT, Snap and ~/.dotnet copies coexist, identify which executable is selected before changing PATH. Do not create guessed symlinks between installation roots.
Issue 3: Missing hostfxr, framework or dependency errors
Packages from mixed Microsoft and Ubuntu feeds can cause these errors. Follow the official package-mix-up repair guide for your installation. Preserve project files and review which apps depend on each runtime before removing packages. Do not run a broad dotnet* purge as a first fix.
Issue 4: A compatible SDK was not found
Check dotnet --list-sdks and read any global.json in the project directory or its parents. It may request a version you do not have. Install the supported SDK required by the project or deliberately update its pin. Do not delete a team’s pin just to hide the error.
Issue 5: NuGet restore or package download fails
Return to HelloApp and retry restore to see the underlying error:
Ubuntu terminal
dotnet restore
Check internet access, the system clock, NuGet sources and any managed proxy or certificate settings. Do not disable TLS verification. A missing Newtonsoft namespace usually means the package was not restored or was added to a different project.
Issue 6: Could not find a project, or duplicate top-level statements
Run project commands inside HelloApp, where HelloApp.csproj lives. Linux filenames are case-sensitive. For a file-based app, use the separate script directory. Do not keep hello.cs alongside Program.cs in the console project.
Resume after a failed step
Fix the reported repository, SDK selection or network problem first. Then verify dotnet --list-sdks. For an existing HelloApp project, return to its directory and rerun dotnet restore, dotnet build and dotnet run. You do not need to recreate the project or overwrite Program.cs to recover from a restore failure.
9. Update or remove .NET
Update the APT installation
Install available updates for packages already on your system:
Ubuntu terminal
sudo apt update && sudo apt upgrade
Review APT’s changes. This upgrades other installed Ubuntu packages too and can restart services. Schedule updates appropriately on a server. It does not switch a net10.0 project to net11.0 or update its NuGet references; rebuild and test applications after updating.
Remove the SDK when you no longer need it
Before removal, check which projects and tools depend on the SDK. Review APT’s proposed removals:
Ubuntu terminal
sudo apt remove dotnet-sdk-10.0
This removes the SDK package, not your HelloApp source directory. Runtime dependencies may remain installed. If you installed .NET 11, remove it separately with sudo apt remove dotnet-sdk-11.0.
Only if no application needs the 10.0 runtimes, remove them explicitly. This can break dependent apps and can remove SDK packages that depend on them:
Review dependencies before using autoremove. If you added the backports PPA and no longer need any packages from it, remove its repository with sudo add-apt-repository --remove ppa:dotnet/backports, then run sudo apt update. Removing a PPA does not remove or downgrade packages already installed from it.
Frequently asked questions
Do I need the SDK or just the runtime?
Install dotnet-sdk-10.0 to create, build and run C# projects. Use aspnetcore-runtime-10.0 for an existing ASP.NET Core app, or dotnet-runtime-10.0 for an app that does not need ASP.NET Core. The SDK already includes its matching runtimes.
Do I need the Microsoft APT repository on Ubuntu 24.04 or 26.04?
No. Use Canonical-maintained .NET packages from Ubuntu feeds on these releases. Do not add packages-microsoft-prod.deb for this installation, and avoid mixing Ubuntu and Microsoft .NET packages.
Can .NET 10 and .NET 11 SDKs be installed together?
Yes. Versioned APT SDK packages can coexist. Use dotnet --list-sdks to check them and a global.json file when a project needs a specific SDK. Without a selection file, the CLI normally chooses the highest installed SDK.
Does installing .NET let me run every Windows C# app?
No. Applications using Windows-only frameworks such as WPF or Windows Forms do not become Linux applications by installing .NET. The code and its dependencies must support Linux.
Does dotnet publish -c Release include the runtime?
For the ordinary console project in this guide, the default output is framework-dependent and needs the matching runtime on the destination. Self-contained publishing requires an explicit deployment choice and an appropriate target platform.
Can I run C# without creating a project?
Yes. With the .NET 10 SDK or later, use dotnet run hello.cs for a file-based app. Keep that file outside an existing C# project directory to avoid including it in the project build.