dotnet/efcore · error · InvalidOperationException

' . ' and ' . ' are both mapped to column ' ' in ' ', but…

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 mapped to the same column disagree on IsConcurrencyToken. Because the column backs a single physical store column, EF cannot honor one side's optimistic-concurrency check while ignoring the other's, so it rejects the model. Note this is independent of the store-generated token sharing handled separately.

Solutions

  1. Mark both properties as concurrency tokens (IsConcurrencyToken(true) on both).
  2. Remove IsConcurrencyToken from the side that does not need it so both match.
  3. If only one side should track concurrency, remap the other property to its own column.

Example fix

// before
modelBuilder.Entity<Document>().Property(d => d.Version).IsConcurrencyToken();
modelBuilder.Entity<DocumentBlob>().Property(b => b.Version); // shared column, not a token

// after
modelBuilder.Entity<Document>().Property(d => d.Version).IsConcurrencyToken();
modelBuilder.Entity<DocumentBlob>().Property(b => b.Version).IsConcurrencyToken();
Defensive patterns

Strategy: validation

Validate before calling

foreach (var (col, props) in sharedColumnGroups)
{
    var flags = props.Select(p => p.IsConcurrencyToken).Distinct().ToList();
    if (flags.Count > 1)
        Console.WriteLine($"Column {col} has conflicting concurrency-token settings");
}

Try / catch

try { _ = db.Model; } catch (InvalidOperationException ex) when (ex.Message.Contains("different concurrency token configurations")) { // make IsConcurrencyToken consistent on both properties }

Prevention

When it happens

Trigger: ValidateCompatible() checks property.IsConcurrencyToken != duplicateProperty.IsConcurrencyToken on two properties sharing a column. One was marked IsConcurrencyToken(true) (or [Timestamp]) and the other was not.

Common situations: Table-splitting where the principal's token column overlaps with a dependent property but only one side opts into concurrency checking; refactoring that moved a token onto only one half of a split table.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/ceb11654385ac5bd. Report an issue: GitHub.

Appendix: 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 3a2006ef56)