---
title: What is a GEDCOM file
slug: what-is-a-gedcom-file
description: A plain text file, one fact per line, that every genealogy program can read and none reads the same way. What the format is and where it loses data.
tools: [inspect, gedcom-validator]
difficulty: beginner
time: 10 minutes
lastChecked: 2026-09-03
published: 2026-09-03T10:55:00+02:00
---

# What is a GEDCOM file

A GEDCOM file is how one genealogy program hands a family tree to another. It ends in `.ged`, it is plain text, and every program that touches family history can read it.

This page is written because the file arrives and nobody explains it. The definitional answer is well covered: FamilySearch's wiki, gedcom.io and the specification itself all describe the format, and none of them is wrong. What follows is the same description with the part those pages leave out, which is where the format loses your work.

## What is in one

Six lines from a real export:

```
0 @1@ INDI
1 NAME Max /Mustermann/
1 SEX M
1 BIRT
2 DATE 1 JAN 1980
1 FAMC @F1@
```

Every line has three parts.

The **level** is the first number. `0` starts a new record. A line at level 1 belongs to the record above it, and a line at level 2 belongs to the level 1 line above it. That is the whole nesting rule.

The **tag** is the word after the level. `INDI` is an individual, `FAM` a family, `NAME` a name, `BIRT` a birth, `DATE` a date, `SOUR` a source. Tags are three or four letters, defined by the specification, and a tag starting with an underscore is one a program invented.

The **value** is the rest of the line. In `NAME Max /Mustermann/` the slashes mark the surname, which is how the format tells a family name from a given name in a culture-neutral way.

`@1@` is an identifier, called an xref. `@F1@` on the last line is a pointer to a family record elsewhere in the file. Relationships in a GEDCOM are pointers between records, not nesting, and a pointer to a record that does not exist is the single commonest fatal error in the format.

A file is a header, then records, then a trailer:

```
0 HEAD
1 SOUR AHN
1 GEDC
2 VERS 5.5.1
1 CHAR UTF-8
0 @1@ INDI
...
0 TRLR
```

The header states which program wrote the file, which version of the specification it follows and which character set the bytes are in. Those three lines decide how everything after them is read.

## What causes the losses

Three versions are in use, and they are not the same format.

**5.5** dates from 1996 and mandates ANSEL, a 1985 library character set. **5.5.1** dates from 1999, is the version most programs export, and permits UTF-8. **7.0** arrived in 2021, drops ANSEL entirely, changes how long text is continued across lines, and adds a schema mechanism for extension tags. A 5.5.1 file and a 7.0 file both end in `.ged` and are not interchangeable.

Then every program adds its own tags. `_APID` is Ancestry's link from a citation to a record image. `_UID` is a per-record identifier, written four different ways by four programs. None of these is in the specification, so an importer meeting one may map it, keep it as text, or drop it silently.

The result is the thing nobody says out loud: the file transfers people reliably and transfers everything attached to those people unreliably. Sources, notes, media links and custom events are the parts that go missing, and the destination usually says nothing.

```mermaid
flowchart TD
  P["Your genealogy program"] --> E["Export as GEDCOM"]
  E --> H["Header: version, producer, charset"]
  E --> R["Records: INDI, FAM, SOUR, NOTE, OBJE"]
  E --> X["Extension tags: _APID, _UID, and the rest"]
  H --> I["Another program imports it"]
  R --> I
  X --> D{"Does the importer know this tag?"}
  D -- "yes" --> I
  D -- "no" --> L["Dropped, or kept as text. Usually with no message"]
```

## The steps

Numbers below are from `fixtures/public/Musterstammbaum.ged`.

1. Open [File Inspector](/inspect) and drop your file. It parses in your browser; the file does not leave your machine.
2. Read **Header**. On this fixture **GEDCOM version** reads `5.5.1`, **Producer** reads `AHN (Ahnenblatt) 2.99g`, **Declared charset** reads `UTF-8`, **Decoded as** reads `utf-8 with BOM` and **Line endings** reads `LF`. Those facts determine how everything after the header is read.
3. Read **Records by type**. On this fixture `INDI 20`, `FAM 11`, and `HEAD`, `SUBM` and `TRLR` at 1 each. Individuals and families are the two record types every tree has. `SOUR`, `NOTE`, `OBJE` and `REPO` appear when the tree carries citations, notes, media or archives.
4. Read **Problems**. On this fixture the title reads `Problems: 0 errors, 0 warnings, 0 info`. Any row here is a fault in how the file is written rather than in what it says.
![File Inspector reading a 7,175-byte export: the header block naming GEDCOM 5.5.1, Ahnenblatt 2.99g and UTF-8, and Records by type listing 20 INDI, 11 FAM and one each of HEAD, SUBM and TRLR.](/kb/shots/what-is-a-gedcom-file-inspector.jpg)
5. Open [GEDCOM Validator](/gedcom-validator) and drop the same file. The header line states how many rules ran and what was checked: records, individuals, families, pointers, dates and facts.
6. Read the category table. `structural` is whether the file is written correctly. `referential` is whether the pointers resolve. `logical` is whether the content can be true. `encoding` is whether the bytes match the declared charset.
7. Read the three severity counts. An `error` blocks an import. A `warning` is a fact worth checking. An `info` is a note about the file, such as a header with no `SUBM` pointer.

## What to check when it worked

- **Header** names a GEDCOM version. `unknown` means the header is missing or damaged.
- The `INDI` count matches the size of the tree you exported.
- **Problems** in File Inspector is empty, or holds only `info` rows.
- GEDCOM Validator reports 0 errors under `structural` and 0 under `referential`. Those two decide whether another program can read the file at all.
- The producer line names the program you exported from. Something else means the file passed through another program on the way.

## What to do when it did not

**The version reads `unknown`.** The header has no `GEDC` and `VERS` pair. Every version-specific rule is then a guess. [GEDCOM error messages, decoded](/how-to/decode-gedcom-error-messages) covers a damaged header.

**The counts are far below what you exported.** The file was cut, or the parse stopped at a bad line. Read the Problems table for a line number.

**You want to know what a specific site will drop.** The version and the producer decide that. [Which of your custom tags each site will delete](/how-to/what-each-site-deletes-from-your-gedcom) runs a per-destination table over your own file.

**Your file is 7.0 and you want a conformance check.** The specification authors publish a browser-local checker at [gedcom7code.github.io/js-gedcom](https://gedcom7code.github.io/js-gedcom/), which is the reference implementation for that version.

**You want to open it and read it, not audit it.** [Read a GEDCOM without installing anything](/how-to/read-a-gedcom-without-installing-anything) is the shorter path.

## Related

- Pillar: [how to work out what a GEDCOM file actually contains](/how-to/work-out-what-a-gedcom-file-actually-contains)
- Sibling: [read a GEDCOM without installing anything](/how-to/read-a-gedcom-without-installing-anything)
- [How to convert GEDCOM 5.5.1 to 7.0, and what does not survive](/how-to/convert-gedcom-5-5-1-to-7-0-and-what-does-not-survive)
- [What is ANSEL, and why your names look wrong](/how-to/what-is-ansel-and-why-your-names-look-wrong)
