dotnet/efcore · error · InvalidOperationException

The check constraint

Error message

The check constraint '{checkConstraint}' cannot be added to the entity type '{entityType}' because another check constraint with the same name already exists on entity type '{conflictingEntityType}'.

What it means

A check constraint name must be unique within an entity type's hierarchy chain. This throw fires at CheckConstraint construction when the same name already exists in the constraints dictionary attached to the same entity type — i.e. you called HasCheckConstraint twice with the same name on the same entity.

Solutions

  1. Search for all HasCheckConstraint calls using the named constraint across the entity's configurations.
  2. Either rename one of them to a distinct name, or remove the duplicate if both express the same intent.
  3. If the two constraints genuinely differ in SQL, pick a unique name for each (the database requires unique names per table anyway).

Example fix

// before
modelBuilder.Entity<Product>()
    .HasCheckConstraint("ck_price", "[Price] >= 0")
    .HasCheckConstraint("ck_price", "[Price] < 1000000");

// after
modelBuilder.Entity<Product>()
    .HasCheckConstraint("ck_price_nonneg", "[Price] >= 0")
    .HasCheckConstraint("ck_price_cap", "[Price] < 1000000");
Defensive patterns

Strategy: validation

Validate before calling

// Check the name does not already exist on this entity before adding
var et = modelBuilder.Entity<Product>().Metadata;
if (et.FindCheckConstraint("ck_price") is not null)
{
    throw new InvalidOperationException("A check constraint named 'ck_price' already exists on Product.");
}
modelBuilder.Entity<Product>().HasCheckConstraint("ck_price", "[Price] >= 0");

Prevention

When it happens

Trigger: Calling modelBuilder.Entity<T>().HasCheckConstraint("ck_range", "...") twice with the same first argument; an IEntityTypeConfiguration adding a constraint whose name duplicates one declared elsewhere on T.

Common situations: Two configuration classes both adding the same named check; an upgrade where a new check was added without realizing another module already registered the name; copy-paste of a check constraint block.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs:46

        string name,
        string sql,
        ConfigurationSource configurationSource)
    {
        EntityType = entityType;
        ModelName = name;
        Sql = sql;
        _configurationSource = configurationSource;

        var constraints = GetConstraintsDictionary(EntityType);
        if (constraints == null)
        {
            constraints = [with(StringComparer.Ordinal)];
            ((IMutableEntityType)EntityType).SetOrRemoveAnnotation(RelationalAnnotationNames.CheckConstraints, constraints);
        }

        if (constraints.ContainsKey(name))
        {
            throw new InvalidOperationException(
                RelationalStrings.DuplicateCheckConstraint(
                    name, EntityType.DisplayName(), EntityType.DisplayName()));
        }

        var baseCheckConstraint = entityType.BaseType?.FindCheckConstraint(name);
        if (baseCheckConstraint != null)
        {
            throw new InvalidOperationException(
                RelationalStrings.DuplicateCheckConstraint(
                    name, EntityType.DisplayName(), baseCheckConstraint.EntityType.DisplayName()));
        }

        foreach (var derivedType in entityType.GetDerivedTypes())
        {
            var derivedCheckConstraint = FindCheckConstraint(derivedType, name);
            if (derivedCheckConstraint != null)
            {
                throw new InvalidOperationException(

View on GitHub (pinned to 3a2006ef56)