Darwin Core · dwc:occurrenceID
What you are seeing Your dataset shows fewer records than the file you uploaded.
occurrenceID has to be unique within the published dataset and it should stay with the occurrence at source, so the same record is recognisable across dataset versions and downloads. GBIF states the uniqueness requirement plainly; what it does not publish is exactly what happens when you break it.
We are not going to tell you what breaking it does, because we could not verify it. We looked: GBIF documents the requirement, documents the fallback when the field is absent, and documents a flag for wholesale identifier churn — but not the per-record behaviour when two rows in one dataset share an identifier. It would be easy to write that the later row silently overwrites the earlier one. It is plausible, it is what people assume, and we could not confirm it from GBIF, so it does not belong on this page. Refusing to guess about your data and then guessing about the pipeline would be the same mistake pointed the other way.
What matters is that you do not need the mechanism to act. The requirement is stated, duplicates violate it, and the cost of finding out empirically is a published dataset that disagrees with your file. Check before you publish and the question never comes up.
This is a file-level problem, which is why a per-record validator structurally cannot find it. Every individual row is valid. The defect only exists in the relationship between rows, and you have to hold the whole file at once to see it. We report it as FS_DUPLICATE_OCCURRENCE_ID, and it is one of the checks that exists precisely because the standard's own test suite works one record at a time.
The stability half matters as much as the uniqueness half, and here GBIF does document a consequence. If you regenerate your identifiers next year — row numbers, a fresh UUID per export, a hash of a field you later corrected — every record in your dataset looks new: citations pointing at the old identifiers break, and the same observation can be served twice under two identities. GBIF watches for exactly this: a previously published dataset that alters more than 50% of its existing occurrenceIDs gets flagged by their ingestion management system. That threshold is worth knowing before a routine re-export trips it.
A good occurrenceID is derived from something that will not change: a museum catalogue number with its institution prefix, or a survey code plus site plus date plus a within-visit counter. A bad one is the spreadsheet row number.
Leaving it out entirely does not avoid the problem — it hands the decision to someone else. Where occurrenceID is absent, GBIF's pipeline falls back to building an identifier from the triplet: institutionCode, collectionCode and catalogNumber. That is a reasonable default and it is not yours. Records identified only by triplet are markedly more prone to being mismatched or duplicated across re-harvests, so an absent identifier turns into an unstable one — and the instability shows up later, in somebody else's system, long after you stopped looking.
It also helps to know which kind of duplicate you have, because the community distinguishes three and only one of them is this problem. Exact duplicates match on every field including the identifier. Strict duplicates match on everything except the identifier. Relaxed duplicates match on the fields that matter — taxon, coordinates, date, recorder — while differing elsewhere. A repeated occurrenceID across genuinely different observations is the damaging case, because it is the one where a record you meant to publish is overwritten by another.
occurrenceID values and compare against your row count. Any gap is the number of records you are about to lose.ABC-001 and abc-001 are two identifiers to a computer and one to you.We hold the whole file, so we can see what a per-record check cannot. Drop it in and we will report duplicate identifiers by count, along with everything else we found and everything we refused to interpret. Free until 1 September 2026, 00:00 UTC · no account · your rows are discarded after the check.
Check the file you have →Measured on a file GBIF had already accepted and served — their validator asks will this load, and it had. Every figure is read from ops/data.json, never typed here. We issue no rating and no seal — each finding names the rule it applied.