Before you start
- ✓A full database backup, and a copy of the site files
- ✓A staging copy to upgrade first, never the live site
- ✓A list of every add-on package and backoffice extension, and whether each has a version for Umbraco 17
- ✓.NET 10 installed on every developer machine and build server
- ✓A list of your custom code, especially anything that customises the backoffice
1. Get onto the latest Umbraco 13 and clear out what 17 dropped
Starting from the newest 13 release gives the jump a known-good base (on our own site, 13.13.1). Then we look for what 17 no longer has:
- Custom code built on Umbraco's old API controller, which is gone. It needs rewriting as standard ASP.NET Core code.
- Properties using the legacy Media Picker. Switch them to the current one while you can still test on 13.
- Leftovers such as unused sync folders from earlier versions and one-off import tools.
2. Check every package has a version for 17
This step decides your timeline. Our theme package had no Umbraco 17 release when we started, which held things up until it shipped. We later replaced it with templates we own, so a third-party release can't hold up the next upgrade. Expect to drop abandoned or debug-only packages. Backoffice customisations written in AngularJS must be rebuilt, because the backoffice has used web components since Umbraco 14.
3. Move to .NET 10 and update the packages
Umbraco 17 runs on .NET 10, so the project moves up from .NET 8 (we pinned 10.0.300 so every machine builds alike). Umbraco and each package you keep, such as uSync, forms and import tools, go to their 17 versions. Seeing template changes without a rebuild during development needs one extra package.
4. Remove what Umbraco 17 took away
A build shows what no longer exists. For us: a setup line for the old installer; Smidge, the old CSS and JavaScript bundler, which we replaced with direct links; and macros, which are gone entirely, so any template using one must be rewritten (we retired a leftover grid template).
5. Back up, start the site and let it upgrade the database
With a backup taken, switch on Umbraco's unattended upgrade setting and start the site. Umbraco 17 then upgrades the database itself: converting Block List content, migrating rich text settings, converting dates to UTC and updating its backoffice login system (OpenIddict). Watch the log until it reports completion. Rich text editors move from TinyMCE to TipTap automatically, but check their settings afterwards.
6. Fix what the first start shows you
The backoffice can look fine while the public site fails, because it doesn't use your templates. Load a page of every type and read the log. Our first start showed two failures, covered under What usually goes wrong below.
7. Re-sync your content with uSync
If you use uSync to keep site structure under version control, let it export a fresh set for 17 on first start (ours was 795 items) and treat that as the source of truth. Keep the old files for reference; don't import them.
8. Get ahead of Umbraco 18
The build also warns about features due to be removed in 18. For us the big one was how templates move around the content tree (a page's children, parent, descendants and ancestors). We replaced it now with helpers built on the newer approach, so the next upgrade won't be a rewrite.
What usually goes wrong
From our own projects, not the manual.
Every page of the public site returned an error
An invisible marker character (a UTF-8 byte-order mark) at the start of our template files stopped the template compiler (error RZ2005), which took down every front-end page at once. The backoffice was unaffected. We removed the markers and added an editor setting so they can't come back.
Pages using an old image property broke after the upgrade
A property still used the legacy Media Picker, which Umbraco 17 removed, so the site treated its value as plain text and the part of the page expecting an image crashed. Switching the property to the current media picker fixed it. Do this on 13 before you upgrade.
uSync crashed on startup
Two content files had the same identifier, because a renamed item left its old file behind, and uSync refused to import either. Deleting the stale duplicate fixed it. Check for duplicates before any full import.
Importing a page type failed with a database error
A new property's identifier clashed with a property on a different page type (SQL error 2601). These identifiers must be unique across every page type, not just the one you're editing, so give each new property a fresh one.
The RSS feed and similar features returned nothing
On a multi-language site, Umbraco only lists pages in the current language, and features that run outside a normal page visit, such as an RSS feed, don't have one. Tell them which language to use before they look for pages.
Dates came back without a time zone
Dates read from Umbraco 17 are no longer marked as UTC, so converting them to UTC shifted them. Format dates explicitly, for example in the standard RSS date format, instead of converting them.
Do it yourself, or get help?
If your site uses a handful of well-maintained packages, has no custom backoffice extensions and little custom code, a developer comfortable with .NET can do this in a few days on staging. If you rely on a theme or package with no Umbraco 17 release, have custom backoffice extensions, or can't afford the public site to go down, get help: that's where upgrades stall, and where we spend most of our time on them. Every site's mix is different, so the plan depends on what yours relies on.
Get a developer on it