Error in DocumentUrlAlias Repository when Upgrading from 17.1 to 17.2.x

I have tried upgrading a customer’s website from Umbraco 17.1 to 17.2, but I am getting the error:
'An item with the same key has already been added." from the DocumentUrlAliasRepository.’

For example:
System.ArgumentException: ‘An item with the same key has already been added. Key: (59240e8e-c2e8-4c07-9ab7-3444ac258856, 2, foelelser)’

If I completely remove this content page, and delete all traces in the database, I just get the same error on another page.

It seems to happen in the DocumentUrlAliasRepository on the Save() method, when trying to call ToDictionary() on the IEnumerable aliases.

I will paste the error details below.

```
System.ArgumentException
HResult=0x80070057
Message=An item with the same key has already been added. Key: (59240e8e-c2e8-4c07-9ab7-3444ac258856, 2, foelelser)
Source=System.Private.CoreLib
StackTrace:
at System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException[T](T key)
at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable1 source, Func2 keySelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable1 source, Func2 keySelector) at Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.DocumentUrlAliasRepository.Save(IEnumerable1 aliases)
at Umbraco.Cms.Core.Services.DocumentUrlAliasService.d__23.MoveNext()
at Umbraco.Cms.Core.Services.DocumentUrlAliasService.d__15.MoveNext()
at Umbraco.Cms.Core.Services.DocumentUrlAliasServiceInitializerNotificationHandler.d__3.MoveNext()
at Umbraco.Cms.Core.Events.INotificationAsyncHandler1.<HandleAsync>d__1.MoveNext() at Umbraco.Cms.Core.Events.EventAggregator.<PublishCoreAsync>d__131.MoveNext()
at Umbraco.Cms.Core.Events.NotificationAsyncHandlerWrapperImpl1.<HandleAsync>d__02.MoveNext()
at Umbraco.Cms.Core.Events.EventAggregator.d__112.MoveNext() at Umbraco.Cms.Core.Events.EventAggregator.<PublishAsync>d__32.MoveNext()
at Umbraco.Cms.Core.Events.EventAggregator.d__2`1.MoveNext()
at Umbraco.Cms.Infrastructure.Runtime.CoreRuntime.d__20.MoveNext()
at Umbraco.Cms.Infrastructure.Runtime.CoreRuntime.d__17.MoveNext()
at Umbraco.Extensions.WebApplicationExtensions.d__0.MoveNext()
at Program.<$>d__0.MoveNext() in C:\Solutions\bfa\src\BFA.App\Program.cs:line 65
at Program.(String args)
```

2 Likes

Not sure if it’s directly related, but 17.2.1 was released today. Maybe that fixes you issue.

Thank you for the response Luuk, but I tried upgrading to 17.2.1 as well and I get the same error.

I tried with a fresh database copy of the 17.1 version and upgrade directly to 17.2.1 as well, but no luck.

1 Like

Hey @MSchandorff and welcome to the forum! This one surprised me and I couldn’t quite figure out from your stack trace what the problem might be. Gemini has found an answer for me which sounds very plausible but I have no way of validating it..

If you could try to run the queries it suggests, we might get a bit closer to what is actually going on here!

This was the answer I got:

The error you’re seeing is related to a new feature introduced in Umbraco 17.2 (specifically via PR #21396 and refined in #21571). Umbraco now uses a dedicated DocumentUrlAliasService and a new database table (umbracoDocumentUrlAlias) to store and look up URL aliases more efficiently, rather than parsing them from property data on every request.

The exception An item with the same key has already been added occurs in the DocumentUrlAliasRepository.Save method. This happens because the service is gathering a list of aliases from your existing content and trying to convert them into a dictionary using a key composed of (ContentKey, CultureId, Alias). If this list contains duplicates for that triplet, the ToDictionary call fails.

Potential Causes

  1. Duplicate Aliases in Property Value: If a node has umbracoUrlAlias set to a value like foelelser, foelelser (the same alias twice in the comma-separated list), the parser might be producing two entries for the same node/culture.
  2. Variant Content Conflict: If the umbracoUrlAlias property is marked as invariant (shared across all languages) on a variant document type, the service might be attempting to register the same alias for multiple cultures but hitting a collision if the data structure or query logic is flawed.
  3. Database Inconsistency: There might be multiple “current” versions of a node in the umbracoContentVersion table, causing the initializer to pick up the same property data twice.

Recommended Troubleshooting Steps

1. Identify the offending content

Use the GUID and Language ID from your error message (59240e8e-c2e8-4c07-9ab7-3444ac258856, Language ID 2) to find the exact node and property value:

SQL

SELECT n.id, n.uniqueId, n.text AS NodeName, pd.textValue AS AliasValue, l.languageISOCode
FROM umbracoNode n
JOIN umbracoContentVersion cv ON n.id = cv.nodeId
JOIN umbracoPropertyData pd ON cv.id = pd.versionId
JOIN umbracoPropertyType pt ON pd.propertyTypeId = pt.id
LEFT JOIN umbracoLanguage l ON pd.languageId = l.id
WHERE n.uniqueId = '59240e8e-c2e8-4c07-9ab7-3444ac258856'
AND pt.alias = 'umbracoUrlAlias'
AND cv.current = 1

Check if AliasValue contains the same string twice or if multiple rows are returned for the same language.

2. Clean up duplicate aliases site-wide

You can check if other nodes have duplicate aliases in their property strings using this query:

SQL

SELECT n.id, n.text, pd.textValue
FROM umbracoPropertyData pd
JOIN umbracoPropertyType pt ON pd.propertyTypeId = pt.id
JOIN umbracoContentVersion cv ON pd.versionId = cv.id
JOIN umbracoNode n ON cv.nodeId = n.id
WHERE pt.alias = 'umbracoUrlAlias'
AND cv.current = 1
AND pd.textValue LIKE '%,%' -- Only nodes with multiple aliases

Manually check these for duplicates (e.g., alias1, alias1).

3. Check for multiple “current” versions

Ensure your database doesn’t have data corruption where two versions of the same node are both marked as current:

SQL

SELECT nodeId, COUNT(*) 
FROM umbracoContentVersion 
WHERE [current] = 1 
GROUP BY nodeId 
HAVING COUNT(*) > 1

4. Temporary Workaround

If you cannot find the data issue, you might try to Republish All nodes. While the error happens during initialization (likely before you can access the backoffice), if you can get the site to boot by temporarily clearing the umbracoUrlAlias values in the DB, a “Rebuild Database Cache” and “Republish” might resolve underlying inconsistencies.

Conclusion

This appears to be a bug in the DocumentUrlAliasServiceInitializerNotificationHandler where it fails to de-duplicate the aliases before saving them to the new repository. Since you’ve already confirmed it happens on multiple pages even after deletion, it is highly likely that your data has a common pattern (like redundant comma-separated values) that the new Umbraco 17.2 logic isn’t handling gracefully.

I recommend reporting this on the Umbraco GitHub Issue Tracker with your stack trace, as the service should ideally be using .Distinct() or GroupBy() before calling ToDictionary.

Hi @sebastiaan !

Great news, we found multiple pages with duplicate entries in comma separated values in the umbracoDocumentUrlAliasproperty. Removing those values caused the upgrade to finalize and boot as expected.

The issue, as I see it, is missing validation/sanitation on this special property. We had multiple pages with duplicate values, eg. foelelser, foelelserand UTM, utm. Whether or not the underlying logic is case sensitive is unknown at this point, but we removed the uppercase values, nonetheless.

Anyway, the issue seems to be resolved as of now.

Have you found a fix or solution? I can’t even boot a number of our solutions going from 17.1 to 17.2. Boot fails because an exception is thrown in DocumentUrlAliasService while rebuilding Umbraco Document Url Aliases. The database has been updated - so can’t go back to 17.1 and can’t boot the 17.2 because of the exception in DocumentUrlAliasService.

Hi @rolighed ,
Nick Frederiksen was so kind to answer this on my behalf above.
Our issue was that we populated the umbracoDocumentUrlAlias manually and had duplicate entries.