Upgrading Umbraco 13 to 17: What Actually Breaks
Umbraco 13 to 17 is not a routine package bump. Here is what actually breaks at each version – the backoffice rewrite, removed property editors, the JSON serialization change – and a practical strategy for getting through it without surprises.
Umbraco 13 support ends in December 2026. Umbraco 16 support ends in June 2026. If you are running a 13 site, the LTS clock is already the least interesting problem – the real question is what breaks between here and 17, and whether your team is prepared for it.
The honest answer: more than most upgrade blog posts admit. This is not a minor-version bump. Between 13 and 17 you are crossing the backoffice rewrite, a full JSON serialization change, the removal of several property editors and the entire macro system, and two .NET runtime jumps. Treating it like a routine NuGet update is how projects end up with a broken backoffice in production.
Here is what actually changes, version by version, and what it means for a real project – not a demo site.
Can you jump straight from 13 to 17?
Technically, yes. Umbraco's own guidance says direct upgrades across multiple majors are supported – you will not get deprecation warnings for the versions you skipped, but the upgrade itself will run. In practice, for anything beyond a small brochure site, treat it as a staged migration: 13 → 14 → 15 → 16 → 17, testing at each step. The breaking changes compound, and isolating which version broke your custom property editor or your macro-dependent partial view is far easier one hop at a time than after a five-version leap.
If your codebase is clean and dependency-light, a direct jump with thorough regression testing is defensible. If you have custom AngularJS backoffice extensions, Nested Content, Grid, or macros anywhere in the mix, budget for the staged path.
Umbraco 14: the backoffice gets rebuilt from scratch
This is the version that breaks the most projects, because it is not a refactor – it is a replacement.
AngularJS is gone. The entire backoffice UI was rebuilt as Web Components using Lit and the Umbraco UI Library (“Bellissima”). Any custom backoffice extension, dashboard, or property editor UI built against the old AngularJS framework has to be rewritten, not patched. Component names changed wholesale (umb-button → uui-button, umb-box → uui-box), custom icons need the new “icons” extension type, and custom translations need a “localization” extension.
The API layer changed underneath you. The old /umbraco/api backoffice controllers are replaced by the Management API. UmbracoAuthorizedApiController and UmbracoAuthorizedJsonController are gone. UmbracoApiController still compiles but is obsolete. Custom backoffice-facing endpoints need to move to ManagementApiControllerBase or a standard ASP.NET Core controller.
Newtonsoft.Json is out, System.Text.Json is in. This sounds like plumbing until you have custom property editors or API controllers with serialization assumptions baked in – System.Text.Json is stricter by default, and code that quietly tolerated loose JSON under Newtonsoft can throw where it did not before. This needs real regression testing, not a glance at the changelog.
Nested Content, the legacy Grid, the old Media Picker, and Macros are all removed. Not deprecated – removed. If any of these are in your content models, they need migrating to Block List, Block Grid, or MediaPicker3 before you touch 14. Macros and Partial View Macros have no direct replacement; RTE macros need converting to Block syntax, and partial view macros need converting to element types or standard partial views. On a content-heavy site, this migration step is usually the single biggest line item in the upgrade.
Umbraco 15: the caching model changes
The snapshot architecture is gone. IPublishedSnapshot and IPublishedSnapshotAccessor are removed entirely. Code that injects these directly – common in older custom code and some third-party packages – needs to move to IPublishedContentCache or IPublishedMediaCache. This is an easy one to miss because it compiles fine right up until it does not.
.NET 9. ASP.NET Core 9 compresses static JS/CSS automatically, which can double up with any compression middleware you already run. If you manage your own asset pipeline, check for double-compression and set CompressionEnabled to false in the project file if needed.
ModelsBuilder models need a full rebuild on this version – clear the umbraco/Data/TEMP/InMemoryAuto folder rather than assuming a clean recompile picks everything up.
Umbraco 16: TinyMCE is gone
TinyMCE is removed outright, not deprecated, due to its license change – content is migrated automatically to TipTap on upgrade. If your editors rely on custom TinyMCE plugins or specific toolbar configurations, check them before upgrading; TipTap's contextual style dropdowns were not at full parity as of this release. If you need to keep TinyMCE specifically, you have to install a third-party package before upgrading, not after.
Package migrations became asynchronous and are binary-incompatible with 15-era builds – any custom package with its own migration plans needs rebuilding against 16, not just recompiling.
Umbraco 17: the LTS you are actually upgrading toward
Umbraco 17 is the new LTS, running on .NET 10. A few changes worth knowing before you land here:
- HTTPS is enabled by default. If your appsettings.json assumed HTTP in certain environments, check it explicitly.
- Swagger is gone, replaced by OpenAPI – API docs move from /swagger to /openapi.
- System dates are now stored in UTC, with an automatic migration and configurable timezone handling. Anything doing manual date math against local time needs a look.
- XPath support in the Multinode Tree Picker is removed, and XPath-based picker configurations are silently wiped during upgrade rather than erroring. Reconfigure legacy XPath pickers with Dynamic Root before you upgrade, not after you notice empty pickers in production.
- Dependency bumps worth checking against your own packages: NPoco 5.7.1 → 6.1.0 (major version), Serilog hosting 9.0.0 → 10.0.0.
None of these are individually hard. Together, on a site that has accumulated years of custom editors and content models, they add up to real engineering work.
What this actually costs on a real project
The pattern across all five versions is consistent: Umbraco keeps removing the paths that let you defer a decision – legacy editors, macros, AngularJS extensions, loose JSON handling, XPath configs. Each removal is defensible on its own. Stacked across four major versions, they add up to a project that looks like a routine upgrade on the ticket but behaves like a partial rebuild of your content architecture and backoffice extensions.
The teams that get burned are the ones who scope this as “bump the NuGet packages and see what happens.” The teams that do not are the ones who audit first, checking:
- Which content types still use Nested Content, Grid, or the legacy Media Picker.
- Which templates or RTE fields rely on macros.
- Whether any custom backoffice extensions are still AngularJS.
- Whether any code injects IPublishedSnapshot directly, or has serialization logic that assumes Newtonsoft's leniency.
- Whether any pickers use XPath.
Run that audit before you touch a version number, not during the upgrade.
A sane upgrade strategy
Audit first, upgrade second. Catalog every custom property editor, backoffice extension, macro, and legacy content type before you start – this is the work that actually determines your timeline, not the package update itself.
Stage the upgrade unless your codebase is genuinely clean: 13 to 14 to 15 to 16 to 17, with a working, tested build at each step. It is slower than a single jump, but it turns “something broke somewhere in five major versions” into “something broke in this specific version”, which is a debuggable problem instead of a guessing game.
Budget real time for content model migration. Nested Content, Grid, and macro removal in v14 is usually the largest single cost in the whole upgrade, and it is the one most likely to get underestimated because it looks like a content task rather than a dev task.
Test the backoffice, not just the front end. A green build does not mean your custom dashboards, property editors, or backoffice extensions still render – Bellissima broke a lot of things that never touched the public-facing site.
Why this keeps happening
None of this is Umbraco being reckless. Removing AngularJS, TinyMCE, and legacy editors is the right long-term call – it is a cleaner, faster, more secure platform on the other side. But it means every project built without upgrade discipline in mind accumulates a repayment bill, and that bill comes due in exactly the kind of multi-version jump this post is about.
That is the argument for starting new projects – and re-platforming old ones – on a foundation that is not accumulating that debt in the first place: current dependencies, no legacy editors baked into the content model, no AngularJS backoffice extensions to rewrite later. It is a lot cheaper to stay current one LTS at a time than to face this exact list of breaking changes again in three years.