{"record":{"id":"d2ca0dc0035ee36e","repo":"dgraph-io/dgraph","slug":"there-are-duplicates-in-existing-data-for-predicat","errorCode":null,"errorMessage":"there are duplicates in existing data for predicate [%v].Please drop the unique constraint and re-add it after fixing the predicate data","messagePattern":"there are duplicates in existing data for predicate \\[(.+?)\\]\\.Please drop the unique constraint and re-add it after fixing the predicate data","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgraph/server.go","lineNumber":1845,"sourceCode":"\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\tpredValue = val.Value\n\t\t\t}\n\t\t} else {\n\t\t\tpredValue = dql.TypeValFrom(pred.ObjectValue).Value\n\t\t}\n\n\t\t// Here, we check the uniqueness of the triple by comparing the result of the uniqueQuery with the triple.\n\t\tif !isEmpty(queryResult.Uids) {\n\t\t\tif len(queryResult.Uids.Uids) > 1 {\n\t\t\t\tglog.Errorf(\"unique constraint violated for predicate [%v].uids: [%v].namespace: [%v]\",\n\t\t\t\t\tpred.Predicate, queryResult.Uids.Uids, pred.Namespace)\n\t\t\t\treturn errors.Errorf(\"there are duplicates in existing data for predicate [%v].\"+\n\t\t\t\t\t\"Please drop the unique constraint and re-add it after fixing the predicate data\", pred.Predicate)\n\t\t\t} else if queryResult.Uids.Uids[0] != subjectUid {\n\t\t\t\t// Determine whether the mutation is a swap mutation\n\t\t\t\tisSwap, err := isSwap(qc, queryResult.Uids.Uids[0], pred.Predicate)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif !isSwap {\n\t\t\t\t\treturn errors.Errorf(\"could not insert duplicate value [%v] for predicate [%v]\",\n\t\t\t\t\t\tpredValue, pred.Predicate)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// addQueryIfUnique adds dummy queries in the request for checking whether predicate is unique in the db","sourceCodeStart":1827,"sourceCodeEnd":1863,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/server.go#L1827-L1863","documentation":"After adding a @unique constraint (or while validating a unique mutation), Dgraph compares the unique-check query results with the mutation triple. If the eq(value) query returns more than one UID, the existing data already violates uniqueness — two nodes share the value — so Dgraph cannot enforce the constraint and asks you to drop the @unique directive, fix the data, and re-add it. This is thrown during verifyUnique (edgraph/server.go:1845).","triggerScenarios":"Submitting a mutation touching predicate P with @unique where the unique-check query `func: eq(P, value)` matches 2+ existing UIDs, i.e. the database already contains duplicate values for P, so the constraint cannot be validated against this mutation.","commonSituations":"Applying an ALTER that adds @unique to a predicate whose data already has duplicates (the schema change succeeds but subsequent mutations hit this); an index backfill or data import created duplicates; running the same seed mutation with blank nodes twice; multi-writer workloads that inserted duplicates before the unique check existed (e.g. upgrading from an older Dgraph version without @unique enforcement).","solutions":["Drop the unique constraint: `ALTER { \"drop_attr\": ... }` or re-alter the schema without @unique","Find duplicates with a query like `{ q(func: has(P)) { P uid } }` (or group by value) and delete/merge duplicates so each value appears on exactly one node","Re-apply the ALTER adding @unique after the data is deduplicated","Prevent recurrence: enforce app-level checks or use upsert blocks for all writers; consider `@upsert` directive so conflicting concurrent mutations abort"],"exampleFix":"# before (data has two nodes with email a@b.com; mutation triggers error)\nmutation { set { _:u <email> \"a@b.com\" . } }\n# after\n# 1. alter schema without @unique\n# 2. query duplicates: { dups(func: eq(email, \"a@b.com\")) { uid } } -> delete extras\n# 3. alter schema back with @unique, then run the mutation via upsert","handlingStrategy":"validation","validationCode":"// Before adding @unique (or before mutations), find duplicates:\nq := `{\n  dup(func: has(email)) { uid email }\n}`\n// post-process results: flag values appearing on >1 uid; delete/merge them first","typeGuard":null,"tryCatchPattern":"err := runMutation(ctx, mu)\nif err != nil && strings.Contains(err.Error(), \"duplicates in existing data\") {\n\t// abort pipeline; run dedup job before retrying\n}","preventionTips":["Check data for duplicates before ALTERing @unique onto an existing predicate","Run dedup jobs after bulk imports and before enabling constraints","Avoid seeding with blank nodes more than once","Enable @upsert on predicates requiring strict uniqueness across concurrent writers"],"tags":["dgraph","unique-constraint","data-quality","schema"],"backgroundTag":"duplicate-data-unique-constraint","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}