Services
Custom software developmentUmbraco developmentWeb developmentCRM developmentERP developmentAI & LLM integration.NET development & modernizationE-commerce developmentIntegrations & automationCloud & DevOpsMaintenance, support & project rescueDedicated teams & white-label
Our Work
Case studiesProducts
About Blog Contact
Umbraco

How to upgrade Umbraco 8 to Umbraco 17: a practical migration guide for .NET 10

Umbraco 8 reached end of life in February 2025. Moving to Umbraco 17 means migrating the database through supported steps and rebuilding the code layer on ASP.NET Core and .NET 10. Here is how to plan it.

Key takeaways

  • There is no direct upgrade from Umbraco 8 to 17: content moves through a supported database path while the code is rebuilt on ASP.NET Core.
  • Umbraco documents an 8 to 10 database upgrade, then major upgrades through the closest LTS versions, 13 and then 17.
  • Nested Content, the legacy Grid and macros were removed in Umbraco 14, so their data must be converted to blocks before or during the move.
  • Every custom back-office extension written in AngularJS has to be rewritten for the Web Components back office introduced in Umbraco 14.
  • Package replacements, custom back-office code and template volume drive the effort far more than the number of content nodes.

To upgrade Umbraco 8 to Umbraco 17 you do two separate jobs. The content and database move through a supported migration path (Umbraco 8 to 10, then through the LTS versions to 17), and the code layer is rebuilt, because Umbraco 8 runs on ASP.NET and .NET Framework while Umbraco 17 runs on ASP.NET Core and .NET 10. Umbraco’s documentation is explicit that a direct upgrade from 8 to the latest version is not possible and that custom code and templates must be reimplemented.

Umbraco 8 reached end of life on February 24, 2025. Umbraco 17, released November 27, 2025, is the current long-term support (LTS) version, with full support until November 27, 2027 and security fixes until November 27, 2028. That makes 17 the natural target for anyone still on 8. This guide covers the migration path the docs confirm, what changes in the code and back office, package replacements, testing, cutover and what actually drives effort, with our Jongeneel migration as a worked example.

Why an Umbraco 8 to 17 upgrade is a rebuild of the code layer

Umbraco 9 moved the CMS from ASP.NET MVC 5 on .NET Framework to ASP.NET Core. Umbraco 14 then replaced the AngularJS back office with a new one built on Web Components. A site that skipped all of those versions has to absorb both breaks at once.

What carries over and what does not:

Layer Umbraco 8 Umbraco 17 Migrates?
Runtime .NET Framework (ASP.NET MVC 5) .NET 10 (ASP.NET Core) No, code is rewritten
Content, media, members SQL Server database SQL Server or SQLite Yes, through the database upgrade path
Configuration web.config and /config/*.config appsettings.json Manually moved
Templates Razor views on Umbraco.Web.Mvc.UmbracoViewPage Razor views on Umbraco.Cms.Web.Common.Views.UmbracoViewPage Copied, then edited
Back-office extensions AngularJS Web Components, Lit, TypeScript No, rewritten
Nested Content, Grid, macros Built in Removed since Umbraco 14 Data must be converted
Rich text editor TinyMCE Tiptap (migrated automatically from Umbraco 16) Configuration review needed
JSON serialization Newtonsoft.Json System.Text.Json (since 14) Custom converters reviewed

So the useful mental model is: the database is upgraded, everything that compiles is rebuilt.

The supported content migration path

Umbraco documents the route in two parts.

Step 1: Umbraco 8 to Umbraco 10 (database only)

The official upgrade guide describes this sequence:

  1. Upgrade the Umbraco 8 site to the latest Umbraco 8 release, then back up its database.
  2. Create a clean Umbraco 10 project. If you use Umbraco Forms, install the Forms package there and make sure Forms data is stored in the database on the old site first.
  3. Point the new project’s umbracoDbDSN connection string in appsettings.json at a copy of the version 8 database.
  4. Run the project and accept the upgrade in the installer. This migrates the schema and content.
  5. Copy views, media (into wwwroot/media), stylesheets and scripts, and move custom settings from the .config files into appsettings.json.

The docs call this step “only content migration”. The front end will throw errors until templates are updated.

Step 2: Major upgrades through the LTS versions

From there you follow the major upgrade rules. Umbraco requires you to upgrade to the closest LTS major before moving further, and states that a project on Umbraco 13 can upgrade straight to Umbraco 17. In practice that gives the chain 8 → 10 → 13 → 17, running the database migration at each stop. Umbraco 10 and 13 are both end of life or close to it (13 reaches end of life on December 14, 2026), so these are stepping stones, not places to stay.

Alternative: Umbraco Deploy import with migrations

If you have Umbraco Deploy, it can export content and schema from the old site and transform it on import. The Deploy documentation gives “migrate from a Nested Content property in Umbraco 8 to a Block List in Umbraco 13” as the typical case, and ships artifact and property migrators for Nested Content, the legacy Grid and media pickers. Apart from the Grid migrators, which Deploy adds by default, migrators only run if you register them, so you enable just the conversions you need. Umbraco’s own 13 to 17 guidance describes the same choice: upgrade the existing solution in place, or prepare a fresh solution and move content and schema with Deploy import, which suits older, debt-heavy projects.

The community tool uSync.Migrations also converts Grid content to Block Grid. Its maintainers describe it as a work in progress with no support, to be run only on local copies with backups, so treat it as a helper you verify, not a guarantee.

Converting removed editors before Umbraco 14

Umbraco 14 removed Nested Content, the Grid Layout and macros. Their data has to be in Block List, Block Grid or rich text blocks before your site lands on 14 or later, otherwise those properties lose their editor. Plan this conversion explicitly:

  • Nested Content → Block List (or Block Grid for layout-like use).
  • Grid Layout → Block Grid, including any Doc Type Grid Editor content (Umbraco.Deploy.Contrib has a migrator for it).
  • Macros → partial views or blocks in the Rich Text Editor. Umbraco has a dedicated guide for migrating macros.

What changes in the code

Templates and views

Views mostly survive, with namespace and base class changes. The Umbraco docs show the new form:

@* Umbraco 10+ view header (from the Umbraco upgrade guide) *@
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.HomePage>

Beyond the header, expect to replace Html.Action child actions with view components, update helper calls that changed signature, and rebuild anything that relied on macros or the Grid renderer.

Controllers, composers and services

Every class that touches Umbraco APIs has to be ported to ASP.NET Core patterns: dependency injection through IUmbracoBuilder, IActionResult return types, and new namespaces. A route-hijacking controller looks roughly like this after the move (illustrative, simplified):

// Illustrative: an Umbraco 17 route-hijacking controller
public class ProductPageController : RenderController
{
    public ProductPageController(
        ILogger<ProductPageController> logger,
        ICompositeViewEngine compositeViewEngine,
        IUmbracoContextAccessor umbracoContextAccessor)
        : base(logger, compositeViewEngine, umbracoContextAccessor) { }

    public override IActionResult Index()
    {
        // custom logic, then render the template
        return CurrentTemplate(CurrentPage);
    }
}

Version-specific changes on the way to 17 also land in this layer. Umbraco 15 replaced the published snapshot with new cache services (IPublishedContentCache, IPublishedMediaCache), Umbraco 14 switched to System.Text.Json, and Umbraco 17 stores all system dates in UTC with a migration that runs on upgrade. Background jobs, scheduled tasks and email code usually need the most care because they are rarely covered by UI testing.

The back office since Umbraco 14

The back office (code name Bellissima) is built on the Umbraco UI Library with Web Components, and extensions are registered through package manifests and typically written in TypeScript with Lit. AngularJS is gone. Any custom dashboard, section, property editor or content app from Umbraco 8 must be rewritten. This is often the single biggest line item in the estimate, and it is worth asking whether each extension is still needed before rewriting it.

Package replacements

Many Umbraco 8 packages have no version for 17. Build the inventory early and decide per package: upgrade, replace with a built-in feature, replace with another package, or rebuild.

Umbraco 8 dependency Typical Umbraco 17 answer
Nested Content Block List (built in)
Grid Layout, Doc Type Grid Editor Block Grid (built in)
Macros Partial views, blocks in the Rich Text Editor
TinyMCE customizations Tiptap extensions
nuPickers Contentment data list editors, or a custom property editor
Custom AngularJS property editors Web Component property editors

Check each replacement against the package’s own Umbraco 17 release notes, not just its name.

Worked example: Jongeneel, Umbraco 8 to 17 on .NET 10

Jongeneel is a transport company whose staff use an internal Umbraco platform for inspections, safety checklists, toolboxes, equipment, employee administration and transport planning. It ran on Umbraco 8 and .NET Framework. The brief was to move it onto a supported foundation while keeping the features the business relies on every day. The full write-up is in the Jongeneel case study; the parts that matter for planning your own migration:

  • Risk mapping before code. We analyzed the Umbraco 8 solution’s structure, dependencies and business-critical modules first. That review exposed the migration risks and set the upgrade path.
  • Two upgrades in one move. We migrated the solution to Umbraco 17 and refactored it onto .NET 10. Project structure, dependencies and internal libraries were updated, and custom back-office plugins kept working.
  • A dead package replaced. The deprecated NuPicker plugin had no path forward. We replaced it with Contentment and rebuilt its behavior with equivalent features.
  • Tests as the safety net. xUnit and Moq tests kept checking critical business logic during the migration. Hangfire jobs, notifications and scheduled tasks were maintained and extended.
  • Repeatable builds. Docker supports local development and deployment, CI/CD pipelines produce consistent builds, and Serilog and Sentry monitor background processing in production.

The lesson we would pass on: the content was not the hard part. Plugins, background processing and one unsupported package were, and finding them in the first analysis is what kept daily workflows intact.

Testing strategy

A migration changes everything under the site at once, so test the things users notice and the things nobody watches.

  • Content parity. Compare node counts, published state, URLs and a sample of rendered pages between the old and new site, using the same database snapshot.
  • Converted properties. Open a sample of every document type that had Nested Content, Grid or macros and check the blocks render and edit correctly.
  • Business logic. Put unit tests around services before you port them, then run the same tests on the new code. On Jongeneel, xUnit and Moq covered the critical logic.
  • Background work. Verify scheduled jobs, notifications and imports run, and that dates are correct after the UTC change in Umbraco 17.
  • Editors. Give a few editors a staging back office for their real tasks. The new back office looks different, and short training avoids a support spike after go-live.
  • URLs and SEO. Crawl the old site, crawl the new one and diff the URL lists. Add redirects for anything that changed.

Cutover plan

  1. Freeze content on the Umbraco 8 site, or agree a short window in which edits are re-entered.
  2. Take a final database backup and run the same scripted migration you rehearsed on staging. Rehearse it at least twice, timing each run.
  3. Copy media and verify paths.
  4. Smoke test on the production host before switching DNS or the load balancer.
  5. Switch traffic, keep the Umbraco 8 site and database read-only for a rollback window.
  6. Monitor errors, logs and 404s closely for the first days.

What drives the effort

The size of the content tree matters less than you would think, because the database migration is automated. The estimate is driven by:

  • Custom back-office code. Every AngularJS dashboard, property editor or section is a rewrite.
  • Packages without a 17 version. Each one needs a replacement and a data conversion.
  • Nested Content, Grid and macro usage. The number of document types and the complexity of nested structures decide how much conversion and verification work is needed.
  • Templates and controllers. Count views, surface controllers, route hijacking and child actions.
  • Integrations and background jobs. CRMs, SSO, imports and scheduled tasks need porting and end-to-end testing.
  • Test coverage. Existing tests shorten the project; no tests means writing some first.
  • Hosting changes. Moving to Linux containers, Docker or a new cloud adds work but is often worth doing in the same project.

Pre-migration checklist

  • Inventory packages and mark each one upgrade, replace or remove
  • List all custom back-office extensions and decide which are still needed
  • Find every Nested Content, Grid, macro and TinyMCE customization
  • Map integrations, scheduled jobs and config settings
  • Choose the content path: database upgrade chain or Deploy import with migrators
  • Set up a staging environment on .NET 10 with a copy of production data
  • Write tests for critical business logic before porting it
  • Plan URL redirects and editor training

Migrate or rebuild?

If the content model still fits the business, migrating the database keeps node IDs, URLs and history. If the site carries years of workarounds, or a redesign is coming anyway, a fresh Umbraco 17 build with content imported through Deploy can cost about the same and leave a cleaner result. Umbraco’s own guidance says that for most legacy-heavy cases it makes more sense to build fresh on 17.

Either way, 17 gives you a support window to November 2028 on .NET 10, which Microsoft supports until November 14, 2028. If you need help scoping the move, our Umbraco development team does this work end to end, and our .NET developers handle the runtime and integration side.

OSKI Engineering TeamSenior .NET, Umbraco and AI engineers

Written by the engineers who build and support OSKI client projects, reviewed by our CTO before publishing.

FAQ

Questions readers ask

Anything missing? Send us your question and an engineer will answer, usually within one business day.

Contact us
Can I upgrade Umbraco 8 directly to Umbraco 17?+

No. Umbraco's documentation states that a direct upgrade from Umbraco 8 to the latest version is not possible. The database is migrated through Umbraco 10 first, then upgraded through the LTS versions to 17, while templates and custom code are rewritten for ASP.NET Core.

Is Umbraco 8 still supported?+

No. Umbraco 8 entered its security-only phase on February 24, 2024 and reached end of life on February 24, 2025. It no longer receives security fixes, and it runs on .NET Framework, which current Umbraco versions do not support.

What happens to Nested Content when I upgrade from Umbraco 8?+

Nested Content was removed in Umbraco 14, so it must be converted to Block List or Block Grid. Umbraco Deploy ships migrators for Nested Content and the legacy Grid, and community tools such as uSync Migrations also exist. Whatever you use, verify the converted content on a copy of production data before cutover.

How long does an Umbraco 8 to 17 migration take?+

It depends on the code, not the content volume. The main drivers are the number of custom back-office extensions, packages without an Umbraco 17 version, templates and controllers to rewrite, and integrations. A discovery phase that inventories these is the only reliable way to estimate a specific site.

Should I rebuild on Umbraco 17 instead of migrating?+

If the site has years of technical debt or a design refresh is planned anyway, a fresh Umbraco 17 build with migrated content is often the cleaner option, and Umbraco's own guidance leans toward building fresh on 17 for legacy-heavy solutions. If the content model still fits the business, migrating the database keeps IDs, URLs and history intact.

Start a project

Tell us what you need to ship. We come back with a plan and a price.

A spec, a Figma file or three paragraphs is enough to start.

  1. First reply · from an engineer, not a sales rep
  2. 30-min call · with Roman, our CTO, to clarify scope
  3. After the call · a written proposal with plan, team and price
Roman Oleksuk
Roman Oleksuk, CTOPrefer to talk? Pick a slot in Roman's calendar
We reply from a human mailbox. No newsletters. Your brief stays under NDA on request. We use your details only to reply; see our privacy policy.