Converting Gene IDs: Symbols, Ensembl, Entrez, RefSeq and UniProt
10 min read · Updated August 5, 2026
You have two tables. One uses Ensembl gene IDs, the other uses gene symbols, and you need them joined. You convert one to the other, do the join, and end up with noticeably fewer rows than you started with — or, worse, roughly the right number of rows and some of them silently wrong.
Gene ID conversion looks like a lookup and behaves like a data integration problem. This guide covers what each identifier system actually identifies, the version suffix that quietly breaks most joins, why one ID does not map to one ID, and why some conversions need two steps.
The five systems, and what each one identifies
These are not five names for the same thing. They are maintained by different organisations, they identify different kinds of object, and they have different stability guarantees. Using human TP53 as a worked example:
- Gene symbol: TP53. A short human-readable name assigned by a nomenclature committee — HGNC for human genes, MGI for mouse. Readable, and the least reliable thing to key on. See the next two sections.
- Ensembl gene ID: ENSG00000141510. Ensembl's stable identifier for a gene as an annotated region of a genome assembly. The prefix tells you the object type — ENSG for a gene, ENST for a transcript, ENSP for a protein, ENSE for an exon — and non-human species carry a species tag, so the mouse equivalent looks like ENSMUSG00000059552.
- Entrez GeneID: 7157. NCBI's identifier for a gene, and just an integer with no internal structure. A bare number is unambiguous within NCBI and completely ambiguous outside it, so always label the column.
- RefSeq accession: NM_000546 for the mRNA, NP_000537 for the protein. NCBI's curated sequence records, where the prefix carries real meaning: NM_ is a curated mRNA, NP_ a curated protein, NR_ a non-coding RNA, and XM_/XP_ are computationally predicted rather than curated. An XM_ where you expected an NM_ is a downgrade in evidence, not a formatting variant.
- UniProt accession: P04637. UniProt's identifier for a protein sequence entry, six or ten alphanumeric characters. Note the trap alongside it: P04637's entry name is P53_HUMAN, which is readable and explicitly not stable — UniProt guarantees the accession, not the entry name. Key on P04637.
The version suffix that breaks joins silently
Ensembl and RefSeq identifiers both come in versioned and unversioned forms. You will see ENSG00000141510 in one file and ENSG00000141510.21 in another, or NM_000546 and NM_000546.6. The suffix records which revision of that annotation you are looking at, and it increments whenever the underlying annotation changes — TP53's Ensembl gene version has been through more than twenty of them.
This is the single most common cause of a join that loses rows. A string comparison between ENSG00000141510 and ENSG00000141510.21 fails, and it fails silently: the row does not error, it just does not match, and your merged table comes out short. Worse, files from different pipeline runs may carry different version numbers for the same gene, so even a versioned-to-versioned join fails when the two sides were annotated against different Ensembl releases.
The fix is to strip the version before joining unless you specifically need it — split on the dot and keep the first part, on both sides. Do it deliberately as its own step, and count the rows before and after your join, every time. A join that loses 15% of rows and produces no warning is the normal failure mode here, not an unusual one.
Why gene symbols are the worst thing to key on
Symbols are the identifier everyone reads and the one you should never join on if you have an alternative. Three independent problems stack up.
First, symbols change. Nomenclature committees rename genes as understanding improves, and old symbols persist in older papers and older annotation files. Aliases are also genuinely ambiguous: the same symbol has, historically, referred to different genes in different literatures.
Second — and this one is almost too silly to be real — spreadsheets corrupt them. Excel interprets certain gene symbols as dates: SEPT1 becomes 1-Sep, MARCH1 becomes 1-Mar, and the conversion is applied on import, irreversibly, without a warning. A 2016 study by Ziemann, Eren and El-Osta in Genome Biology scanned the supplementary files of thousands of published papers and found that roughly one in five of those containing Excel gene lists had suffered exactly this corruption. A 2021 follow-up found the rate had not improved. The problem was severe enough that in 2020 the HGNC renamed 27 human genes specifically so that spreadsheets would stop mangling them — which is why SEPT1 is now SEPTIN1 and MARCH1 is now MARCHF1, and why both old and new symbols are in circulation.
Third, symbols are species-scoped and look like they are not. Human TP53 and mouse Trp53 are different genes in different genomes with different identifiers; the capitalisation convention distinguishing them is easy to lose in a pipeline. A symbol-keyed lookup with the species left unspecified will happily return the wrong organism's gene.
One ID does not map to one ID
The mental model that makes conversion feel simple is a one-to-one dictionary. It is wrong in both directions, and the places it breaks are where wrong answers come from.
One gene has many transcripts and many proteins. TP53's Ensembl gene ID corresponds to a canonical transcript, ENST00000269305, plus a substantial number of alternatives. Converting a gene ID to a transcript ID therefore has no single right answer — you get the canonical one, or all of them, and which you want depends on your question. UniProt has the same structure on the protein side, where isoforms are suffixed onto the accession (P04637-2 and so on) and the bare accession refers to the canonical sequence.
The reverse direction collapses. Several transcripts and several proteins map back to one gene, so a transcript-level table converted to gene level will contain duplicate gene IDs, and joining on it without aggregating first multiplies rows. If your merged table is unexpectedly longer than either input, this is why.
And some IDs simply have no counterpart. A gene annotated in Ensembl but not curated in RefSeq, a non-coding gene with no protein and therefore no UniProt entry, a retired identifier from a deprecated annotation — all legitimately return nothing. What matters is that your tooling tells you which inputs failed rather than dropping them, because a silently shortened output is indistinguishable from a successful conversion.
Why some conversions take two steps
If you have used UniProt's ID mapping service, you may have noticed that some conversions you would expect to be available are not. That is a property of how the mapping graph is shaped rather than a gap in the data.
UniProt's mapping graph is hub-and-spoke, with UniProtKB at the centre. Gene symbols, Ensembl IDs, Entrez GeneIDs and RefSeq accessions each map directly to UniProt accessions, but not to each other. So a gene symbol to Ensembl ID conversion is not one operation — it is symbol to UniProt accession, then UniProt accession to Ensembl, two jobs chained together.
This matters beyond the inconvenience, because information is lost at each hop. Anything without a UniProt entry cannot make the trip at all, which quietly excludes non-coding genes from any conversion routed through UniProt. SeqBench's Gene ID Mapper chains the two hops automatically and shows you which step you are on, but the underlying constraint is real: a two-hop conversion has more ways to lose a row than a one-hop one, so check your counts.
Orthologs are a different operation entirely
"Convert my human gene list to mouse" sounds like ID conversion and is not. Converting between identifier systems is a lookup — the same biological object described two ways. Finding the mouse counterpart of a human gene is an inference about evolutionary history, and it can be wrong in ways a lookup cannot.
Human TP53 corresponds to mouse Trp53 (ENSMUSG00000059552), and that is a well-established one-to-one orthology. Plenty of gene families are not so tidy. A gene duplicated in one lineage has several equally valid counterparts in the other, some genes have no ortholog at all, and orthology calls come from a specific method on a specific pair of assemblies, so different resources give different answers for the difficult cases.
Keep the two operations separate in your pipeline and label them differently in your methods. An ortholog mapping is a modelling assumption you should be able to defend; an ID conversion is bookkeeping. Worth also knowing the vocabulary: an ortholog is the corresponding gene in another species descended from a common ancestor, while a paralog is a relative within the same lineage arising from a duplication — TP63 and TP73 are paralogs of TP53, not orthologs, and a tool that returns "homologs" may be giving you both.
A checklist before you join two tables
- Identify what each column actually holds — gene, transcript or protein level — and do not join across levels without aggregating first.
- Strip version suffixes from Ensembl and RefSeq IDs on both sides, as an explicit step.
- Never key on a gene symbol if either table carries a stable ID. If you must, record the species and the nomenclature release.
- Count rows before and after the join. Investigate any drop; a shortened table is the normal symptom of a broken key, and it produces no error.
- Check for duplicated keys on both sides before merging, so a many-to-one relationship does not silently multiply your rows.
- Keep the list of inputs that failed to map, and look at it. Genuine absences and broken formatting look identical in the output but need different fixes.
- Open gene lists in a text editor or read them into a dataframe, not by double-clicking into a spreadsheet. If a collaborator sends you an .xlsx of gene symbols, assume date corruption until you have checked.
Frequently asked questions
Why does my gene ID join lose rows?
The most common cause is a version suffix mismatch — ENSG00000141510 does not string-match ENSG00000141510.21, and the row silently fails to join rather than raising an error. Strip the version from Ensembl and RefSeq IDs on both sides before merging. The other frequent causes are joining across levels (transcript IDs against gene IDs) and keying on gene symbols where one side uses an old alias.
What is the .21 on the end of an Ensembl gene ID?
The annotation version, which increments whenever Ensembl revises that gene's annotation. It is real information but rarely what you want to join on, and files from different Ensembl releases will carry different version numbers for the same gene — so even versioned-to-versioned joins fail across releases. Strip it deliberately as its own pipeline step.
Why do I need two steps to convert a gene symbol to an Ensembl ID?
Because UniProt's ID mapping graph is hub-and-spoke with UniProtKB at the centre: symbols, Ensembl IDs, Entrez GeneIDs and RefSeq accessions each map to UniProt accessions but not directly to one another. A symbol-to-Ensembl conversion is therefore symbol → UniProt, then UniProt → Ensembl. One consequence worth knowing: anything with no UniProt entry, such as most non-coding genes, cannot make the trip at all.
Is it safe to use gene symbols as identifiers?
Not if you have an alternative. Symbols get renamed by nomenclature committees, aliases are genuinely ambiguous between genes, they are species-scoped in a way that is easy to lose (human TP53 versus mouse Trp53), and spreadsheets silently convert some of them to dates. Use a stable ID as the key and carry the symbol along as a label for humans to read.
Why did SEPT1 become SEPTIN1?
Because Excel was converting it to a date. In 2020 the HGNC renamed 27 human genes whose symbols spreadsheets mangled on import — SEPT1 to SEPTIN1, MARCH1 to MARCHF1, and so on. The scale of the underlying problem was documented by Ziemann, Eren and El-Osta in 2016, who found roughly one in five papers with supplementary Excel gene lists contained this corruption; a 2021 follow-up found no improvement. Both old and new symbols remain in circulation, so a symbol-keyed lookup may need to handle either.
Is finding a mouse ortholog the same as converting an ID?
No. An ID conversion is a lookup of the same biological object described in two systems. An ortholog is an evolutionary inference about which gene in another species descends from the same ancestor, computed by a specific method on a specific pair of genome assemblies. Human TP53 to mouse Trp53 is clean, but duplicated gene families have several valid counterparts or none, and different resources disagree on the hard cases. Treat it as a modelling assumption, not bookkeeping.
What is the difference between an ortholog and a paralog?
An ortholog is the corresponding gene in a different species, descended from a common ancestor — human TP53 and mouse Trp53. A paralog is a related gene within the same lineage that arose from a duplication — TP63 and TP73 relative to TP53. A resource that reports "homologs" may be returning both, so check which you are getting before you treat the result as a cross-species mapping.
Related tools
Convert gene symbols, Ensembl, Entrez GeneID, RefSeq and UniProt accessions in batch, and find cross-species orthologs.
Test a gene list for enriched GO terms and Reactome pathways with hypergeometric p-values and BH-FDR correction.
Search a gene and get its exon/CDS structure, a druggability/disease/drug/trial/paper dossier, and a GTEx + Human Protein Atlas expression fingerprint — all in one page.
Look up a variant by rsID, chrom:pos:ref:alt, or HGVS and get its ClinVar significance, gnomAD allele frequencies, and CADD/SIFT/PolyPhen2/REVEL scores in one card.