dotnet/efcore · error · InvalidOperationException
'{entityType1}.{property1}' and '{entityType2}.{property2}'
Error message
'{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but have different concurrency token configurations. What it means
Two properties sharing a column disagree on the IsConcurrencyToken setting (one acts as a row-version token, the other does not). EF Core needs the column's concurrency role to be unambiguous because it affects UPDATE/DELETE WHERE clauses. Thrown from ValidateCompatible.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:1620
var currentScale = property.GetScale(storeObject);
var previousScale = duplicateProperty.GetScale(storeObject);
if (currentScale != previousScale)
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameScaleMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),
property.Name,
columnName,
storeObject.DisplayName(),
currentScale,
previousScale));
}
if (property.IsConcurrencyToken != duplicateProperty.IsConcurrencyToken)
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameConcurrencyTokenMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),
property.Name,
columnName,
storeObject.DisplayName()));
}
var currentTypeString = property.GetColumnType(storeObject);
var previousTypeString = duplicateProperty.GetColumnType(storeObject);
if (!string.Equals(currentTypeString, previousTypeString, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameDataTypeMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),View on GitHub (pinned to dbf9771522)
Solutions
- Mark both properties as concurrency tokens (or neither) consistently.
- If only one entity needs the token, rename it to a distinct column via HasColumnName.
- Move the entity that needs the token to its own table.
Example fix
// before modelBuilder.Entity<Student>().Property(s => s.Version).IsRowVersion(); modelBuilder.Entity<Teacher>().Property(t => t.Version); // after modelBuilder.Entity<Student>().Property(s => s.Version).IsRowVersion(); modelBuilder.Entity<Teacher>().Property(t => t.Version).IsRowVersion();
Defensive patterns
Strategy: validation
Validate before calling
using (var ctx = new MyContext()) { ctx.Model.ToDebugString(); }
var a = ctx.Model.FindEntityType(typeof(Student))!.FindProperty("Version")!.IsConcurrencyToken;
var b = ctx.Model.FindEntityType(typeof(Teacher))!.FindProperty("Version")!.IsConcurrencyToken;
Debug.Assert(a == b, $"Concurrency-token mismatch: {a} vs {b}"); Try / catch
try { using var ctx = new MyContext(); _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("concurrency token configurations"))
{ log.Error("Concurrency-token mismatch on shared column: {Msg}", ex.Message); throw; } Prevention
- Place IsRowVersion()/IsConcurrencyToken() on a shared base property when sibling types share the table.
- Run a model-build test at startup to detect token divergence.
- When splitting tables, decide on a single owner of the row-version column.
When it happens
Trigger: A same-named property on sibling TPH types where one uses IsConcurrencyToken() (or [Timestamp]/IsRowVersion) and the other does not; an owned type whose shared column is a token on one side only; table splitting where only one entity treats the column as a token.
Common situations: Adding optimistic concurrency to one entity in a hierarchy but forgetting the sibling that shares the column; migrating from byte[] RowVersion to uint32 with Xmin where one side forgot to mark the token; misusing [Timestamp] on a shared column.
Related errors
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
- '{entityType1}.{property1}' and '{entityType2}.{property2}'
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/ceb11654385ac5bd.
Report an issue: GitHub.