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 are configured with different maximum lengths ('{maxLength1}' and '{maxLength2}'). What it means
EF Core detected two properties (on different entity types sharing the same table) that map to the same column but specify conflicting MaxLength facets. The validator cannot decide which length to use for the physical column, so model finalization aborts. This is thrown from ValidateCompatible during the shared-table (TPH/table-splitting/owned) compatibility check.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:1550
/// <param name="property">A property.</param>
/// <param name="duplicateProperty">Another property.</param>
/// <param name="columnName">The column name.</param>
/// <param name="storeObject">The identifier of the store object.</param>
/// <param name="logger">The logger to use.</param>
protected virtual void ValidateCompatible(
IProperty property,
IProperty duplicateProperty,
string columnName,
in StoreObjectIdentifier storeObject,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
// NB: Properties can have different nullability, the resulting column will be non-nullable if any of the properties is non-nullable
var currentMaxLength = property.GetMaxLength(storeObject);
var previousMaxLength = duplicateProperty.GetMaxLength(storeObject);
if (currentMaxLength != previousMaxLength)
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameMaxLengthMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),
property.Name,
columnName,
storeObject.DisplayName(),
previousMaxLength,
currentMaxLength));
}
if (property.IsUnicode(storeObject) != duplicateProperty.IsUnicode(storeObject))
{
throw new InvalidOperationException(
RelationalStrings.DuplicateColumnNameUnicodenessMismatch(
duplicateProperty.DeclaringType.DisplayName(),
duplicateProperty.Name,
property.DeclaringType.DisplayName(),View on GitHub (pinned to dbf9771522)
Solutions
- Pick one canonical MaxLength and apply the same value to both properties via HasMaxLength(n).
- If the columns are genuinely different, give them distinct column names with HasColumnName on at least one side, or move one type to its own table via ToTable.
- Remove the explicit MaxLength from one property so it inherits the CLR type default, matching the other.
- Centralize shared-column facets in a shared base type or an IEntityTypeConfiguration to prevent divergence.
Example fix
// before modelBuilder.Entity<Student>().Property(s => s.Name).HasMaxLength(100); modelBuilder.Entity<Teacher>().Property(t => t.Name).HasMaxLength(200); // after (shared 'People' table, one canonical length) const int NameLen = 200; modelBuilder.Entity<Student>().Property(s => s.Name).HasMaxLength(NameLen); modelBuilder.Entity<Teacher>().Property(t => t.Name).HasMaxLength(NameLen);
Defensive patterns
Strategy: validation
Validate before calling
// At startup (Program.cs / a test) force model finalization to surface shared-column conflicts early.
using (var ctx = new MyContext())
{
ctx.Model.ToDebugString(); // triggers ValidateCompatible; throws on MaxLength mismatch
}
// Optionally: assert facet parity in a unit test.
var a = ctx.Model.FindEntityType(typeof(Student))!.FindProperty("Name")!.GetMaxLength();
var b = ctx.Model.FindEntityType(typeof(Teacher))!.FindProperty("Name")!.GetMaxLength();
Debug.Assert(a == b, $"MaxLength mismatch: {a} vs {b}"); Try / catch
// During app bootstrap, wrap model warm-up to produce a friendly error.
try { using var ctx = new MyContext(); _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("maximum lengths"))
{
log.Error("Shared-column MaxLength mismatch. Align HasMaxLength on sibling entities sharing a table: {Message}", ex.Message);
throw;
} Prevention
- Centralize shared-column facets in a shared base type or IEntityTypeConfiguration<T> so siblings cannot diverge.
- Add a unit test that builds the model once at test-startup; any facet mismatch fails fast before runtime.
- Use HasColumnName deliberately when two same-named properties must have different facets.
- Review migrations diffs after touching any property on an entity in a TPH hierarchy or table-splitting setup.
When it happens
Trigger: A TPH hierarchy (e.g. Student and Teacher both inheriting Person) where each declares an Address property with different HasMaxLength calls; or two entity types mapped to the same table via table splitting / ToTable(t) / owned types whose matching columns set different MaxLength. Fails on first DbContext use or DbContextOptionsBuilder.UseXxx finalization.
Common situations: Two developers independently added the same-named property to sibling derived types with different lengths; an owned entity and its owner both configure the shared column; partial model where one side uses data annotations ([MaxLength(100)]) and the other uses Fluent API with a different value; refactoring a property without updating the mirrored one.
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/8ce789bdb1c82a8e.
Report an issue: GitHub.