Primer Dimer Check Tutorial: Testing ΔG Rules on the CDC qPCR Primers
Primer Dimer Check Tutorial: Testing ΔG Rules on the CDC qPCR Primers
A primer dimer checker gives you a ΔG and a verdict. The hard part is deciding what to do with it. Is −7 kcal/mol a problem? At what temperature? Does it matter that the structure sits on a probe and not a primer?
Rules of thumb answer that in the abstract. This page tests them on a primer set where we know what actually happened: the CDC 2019-nCoV real-time RT-PCR panel. It is one of the few published qPCR panels with documented dimer outcomes:
- N3 was removed from the panel in March 2020. A later CDC investigation found that the 3′ end of the N3 probe paired with the 3′ end of the N3 reverse primer. That produced short probe-containing products and fluorescence in wells with no template.
- N2: one diagnostic lab reported late non-specific amplification in 57.1% of its no-template controls. It traced this to three N2 interactions (the probe with itself, and each N2 primer with the probe) and reduced it by changing Mg²⁺, temperature and concentrations.
- N1 had false positives in the first manufactured lot. CDC traced those to contamination with a synthetic template, not to dimers.
- RNase P (RP), the human control: we found no dimer report.
So the question is concrete: does a dimer check point at N3 and N2, and leave N1 and RP alone? We ran the oligos through:
- a consecutive Watson–Crick dimer model, the method the Runcell primer dimer checker documents on its page, re-implemented in Python and checked against the live tool;
- Primer3’s thermodynamic alignment (
primer3-py), which also scores mismatches, bulges and loops, plus its 3′-end stability calculation; - Primer3’s
check_primerstask with its default limits.
Every number below comes from a script run on 2026-10-05. To check your own pair, paste it into the primer dimer checker . The rest of this page is about what its output can and cannot tell you.
Environment and sources:
| Item | Version / source |
|---|---|
| Python | 3.14.2 |
| primer3-py | 2.3.1 |
| Biopython | 1.88 |
| N1, N2, RP sequences | CDC “Research Use Only 2019-nCoV Real-time RT-PCR Primers and Probes” page, archived 2020-12-31 (the live cdc.gov page returned HTTP 403) |
| N3 sequences | The same CDC page, archived version reviewed 2020-01-25 |
| Assay conditions | CDC-006-00019 Rev. 08 instructions for use (FDA EUA), effective 2023-03-07 |
| N3 outcome | Lee et al., PLoS ONE 16(12): e0260487 (2021), CDC investigation of the first panel lot |
| N2 outcome | ”Adjusting RT-qPCR conditions to avoid unspecific amplification in SARS-CoV-2 diagnosis” |
| Primer3 defaults | Primer3 manual |
| Templates | NCBI MN908947.3 (SARS-CoV-2 Wuhan-Hu-1), NM_006413.5 (human RPP30 mRNA) |
The oligos, and where they land
CDC uses primers at 500 nM and probes at 125 nM. Each probe carries FAM on the 5′ end and a quencher on the 3′ end. Before scoring anything, we checked that every sequence matches its template exactly:
N1-F GACCCCAAAATCAGCGAAAT 20 nt GC 45.0% MN908947.3 28287-28306 strand +
N1-R TCTGGTTACTGCCAGTTGAATCTG 24 nt GC 45.8% MN908947.3 28335-28358 strand -
N1-P ACCCCGCATTACGTTTGGTGGACC 24 nt GC 58.3% MN908947.3 28309-28332 strand +
N1 amplicon 28287-28358 = 72 bp
N2-F TTACAAACATTGGCCGCAAA 20 nt GC 40.0% MN908947.3 29164-29183 strand +
N2-R GCGCGACATTCCGAAGAA 18 nt GC 55.6% MN908947.3 29213-29230 strand -
N2-P ACAATTTGCCCCCAGCGCTTCAG 23 nt GC 56.5% MN908947.3 29188-29210 strand +
N2 amplicon 29164-29230 = 67 bp
RP-F AGATTTGGACCTGCGAGCG 19 nt GC 57.9% NM_006413.5 28-46 strand +
RP-R GAGCGGCTGTCTCCACAAGT 20 nt GC 60.0% NM_006413.5 73-92 strand -
RP-P TTCTGACCTGAAGGCTCTGCGCG 23 nt GC 60.9% NM_006413.5 49-71 strand +
RP amplicon 28-92 = 65 bpN3 as CDC listed it in January 2020:
N3-F GGGAGCCTTGAATACACCAAAA 22 nt MN908947.3 +hits=1 -hits=0 at 28681
N3-R TGTAGCACGATTGCAGCATTG 21 nt MN908947.3 +hits=0 -hits=1 at 28732 (-)
N3-P(C) ACCACATTGGCACCCGCAATCCTG 24 nt MN908947.3 +hits=0 -hits=0
N3-P(T) ATCACATTGGCACCCGCAATCCTG 24 nt MN908947.3 +hits=1 -hits=0 at 28704The N3 probe was published with a degenerate base (AYC…, Y = C or T). We scored both
versions. Only the T version matches the Wuhan-Hu-1 reference. The two give identical
numbers for every pair with N3-F and N3-R, and differ by less than 0.6 kcal/mol for the
probe’s self-dimer. Below, “N3-P” means the T version.
To get the other strand of a primer, for example to search for a reverse primer in a template, use the reverse complement tool . For the GC% of a whole amplicon, use the GC content calculator .
Finding 1: a consecutive-pair checker at common limits misses N3
The consecutive Watson–Crick model only scores unbroken runs of 3 or more pairs. Its limits are the ones the checker publishes: “Check” below −5 kcal/mol if a 3′ end is paired and below −6 if not, “Strong” below −9. Our Python version reproduces the four worked examples on the checker’s page exactly (−6.35, −1.70 and −0.45 kcal/mol, and a hairpin of −6.00 kcal/mol with Tm 69.9 °C). We also entered N3-R with N3-P, and N2-F with N2-P, into the live checker. It returned the same values as our script.
For N3, at 25 °C under Primer3’s default salt:
pair WC dG bp 3p verdict P3 dG P3end(a3p) P3end(b3p) WC stretch
N3-RxN3-P(T) -5.38 6 no OK -7.62 -5.47 -7.09 GATTGC (a 9-14) x b 16-21Columns: the consecutive model’s ΔG, base pairs, whether a 3′ end is in that stretch, and its verdict; then Primer3’s global ΔG and its 3′-end stability for the first and the second oligo’s 3′ end; then the stretch itself.
The strongest consecutive stretch between N3-R and its probe is 6 bp (GATTGC) in the
middle of the reverse primer, at −5.38 kcal/mol. It does not touch a 3′ end, so the limit
is −6 and the verdict is OK. The live checker reports “No problem structures” for this
pair. No N3 pair is flagged at all.
For the panel that stayed in use, the same rules flag one pairing out of 18 in the real
wells: the N2 probe with itself (6 bp AGCGCT, −7.05 kcal/mol). That structure was
one of those the N2 report identified.
Why the miss: CDC’s analysis describes multiple regions of complementarity between the two 3′ ends, not one long unbroken run. A model that only scores unbroken runs scores each short run on its own, and here the strongest one is in the middle of the primer. A clean result from a consecutive-pair checker is not a clean result for 3′ ends that pair with mismatches or gaps.
Finding 2: Primer3’s 3′-end stability puts N3 near the top
Primer3 can also score only the structures in which the 3′ end of one oligo is paired
with the other (calc_end_stability in primer3-py), allowing mismatches and gaps. It
gives one number per direction: the 3′ end of A on B, and the 3′ end of B on A. We ranked
all 24 pairings in the four wells (each oligo with itself and with the others in its
well) at 25 °C, by Primer3’s global ΔG and by the more negative of the two 3′-end scores:
| Rank | By Primer3 global ΔG | ΔG | By 3′-end stability | ΔG | Whose 3′ end |
|---|---|---|---|---|---|
| 1 | N2-R × N2-R | −8.74 | N3-R × N3-P | −7.09 | N3-P |
| 2 | N2-P × N2-P | −8.13 | RP-P × RP-P | −6.86 | RP-P |
| 3 | N1-F × N1-P | −8.11 | N2-F × N2-P | −5.78 | N2-F |
| 4 | RP-R × RP-R | −7.93 | N2-P × N2-P | −5.59 | N2-P |
| 5 | N3-R × N3-P | −7.62 | RP-F × RP-P | −4.70 | RP-P |
| 6 | N3-F × N3-P | −6.97 | N1-F × N1-P | −4.59 | N1-P |
| 7 | N1-P × N1-P | −6.94 | N1-R × N1-R | −4.37 | N1-R |
| 8 | RP-P × RP-P | −6.86 | N3-R × N3-R | −3.69 | N3-R |
kcal/mol, 25 °C, 50 mM Na⁺, 1.5 mM Mg²⁺, 0.6 mM dNTP. Bold: interactions named in the CDC and N2 reports. The third N2 interaction the report names, N2-R × N2-P, ranks 10th by global ΔG (−6.59) and 15th by 3′-end stability (−2.75).
What the ranking shows, and what it does not:
- By 3′-end stability, the N3 pair is first and two of the three reported N2 interactions are third and fourth. The RP probe with itself is second, and we found no report about it. N2-R × N2-P is far down the list.
- The top N3 score is the probe’s own 3′ end (−7.09), which the quencher blocks. The N3 primer’s 3′ end on the probe scores −5.47. Counting only primer 3′ ends, the ones a polymerase can extend, the top two of 24 are N2-F on the N2 probe (−5.78) and N3-R on the N3 probe (−5.47). Next is RP-F on the RP probe (−4.46).
- By global ΔG, N2 is near the top but N3 is fifth, behind an N1 pair and an RP self-dimer.
- Primer3’s best global alignment for N3-R × N3-P is the same internal
GATTGCstretch the consecutive model found. The 3′-end scores come from separate calculations, one per direction. They do not show that both 3′ ends pair in the same structure. CDC’s sequencing is what shows that.
This is two documented failures and one panel, not a validation study. The useful reading is narrower than “sort by 3′-end stability”: a strong 3′-end score involving a probe is worth a second look even when the overall ΔG looks moderate. Check whose 3′ end it is, and look at both directions.
The code for the N3 numbers is at the end of Finding 5.
Finding 3: a probe is not safe because its 3′ end is blocked
The probe’s 3′ quencher stops the polymerase from extending the probe. It does not stop a primer from extending along the probe. CDC sequenced the products in N3 no-template wells. Between 29% and 61% were duplexes or triplexes that included the N3 probe, which would generate fluorescence with no virus present.
So in a probe assay, two kinds of dimer behave differently:
- Primer–primer dimers have no probe site. They usually cost sensitivity (they use up primers and polymerase) rather than add signal.
- Primer–probe structures that put an extendable primer 3′ end on the probe can produce probe-containing products, and those can show up as signal in the no-template control. That is the N3 case. A paired probe 3′ end on its own cannot start extension, because the quencher blocks it.
N2-F × N2-P is the structure to watch in the current panel for this reason: the last bases
of N2-F (GCAAA) pair with the probe, and the N2 report notes N2 forward primer–probe
homology at the 3′ end.
Finding 4: weak at the annealing temperature is not the same as safe
At 55 °C, the annealing and extension temperature in the CDC protocol, nothing crosses the consecutive model’s limits or a −6 kcal/mol Primer3 cutoff in any well. That includes N3. Primer3 scores N3-R × N3-P at −2.56 kcal/mol at 55 °C.
N3 still failed under that protocol. A reaction also spends time at lower temperatures: during setup, and in the CDC protocol for 2 minutes at 25 °C and 15 minutes at 50 °C for reverse transcription before the first denaturation. Once a short extended product exists, it copies itself in every cycle from then on.
The N2 lab’s fix supports reading it this way. Its best conditions raised the extension temperature to 63 °C, set MgSO₄ to 6 mM, and lowered primer and probe concentrations (213 nM primers and 54 nM probe, against CDC’s 500 and 125). Before the change, the lab saw late non-specific amplification in 56.4% of negative samples and 57.1% of no-template controls. After it, the rate was 11.5% across negative samples and no-template controls together (217 reactions). Lower, but not gone.
Score at 25 °C to find structures. Use the annealing-temperature score to judge how much a cycling change can help. A low 55 °C score is not proof of safety.
Finding 5: Primer3’s default limits flag N1 twice
N1 has no dimer problem on record, and its first-lot false positives were contamination.
Primer3’s check_primers task, with every setting at its default, still objects to it:
N1-F Tm at 50 nM : 56.7 C
N1-F Tm at 500 nM: 59.9 C
N1-R hairpin Tm : 51.1 C
N1-R self-dimer dG at 25 C: -6.79 kcal/mol
N1-R self-dimer dG at 55 C: -2.89 kcal/mol
left : considered 1, low tm 1, ok 0
right: considered 1, ok 1
N1-R alone: considered 1, high hairpin stability 1, ok 0
N3-R x N3-P dG at 25 C : -7.62 kcal/mol
3' end of N3-R on the other: -5.47 kcal/mol
3' end of N3-P on the other: -7.09 kcal/mol- N1-F: low Tm. Primer3 calculates 56.7 °C. The Primer3 manual gives the default minimum as 57 °C. Setting the minimum to 56 °C makes N1-F pass in our run.
- N1-R: hairpin. Primer3 calculates a hairpin Tm of 51.1 °C. The manual gives the default maximum as 47 °C, which it describes as 10 °C below the default minimum primer Tm. Checking N1-R on its own gives “high hairpin stability”. Raising the limit to 52 °C clears it in our run.
Two caveats from the run itself:
- In the default pair check, the right primer shows
ok 1. Its hairpin failure only appears when the left primer passes or when it is checked alone. When Primer3 rejects a pair, check each oligo separately. - With the Tm floor at 56 °C, Primer3 still returned the pair even though N1-R’s line
reported the hairpin failure (
PRIMER_PAIR_EXPLAIN: considered -1, ok 1). We did not work out why. Read the per-oligo lines, not only the pair count.
What this says about the limits: they are a design margin. The hairpin limit is a fixed 47 °C, which the manual sets 10 °C below the default minimum primer Tm of 57 °C. N1-R’s hairpin at 51.1 °C is 4.1 °C over that limit, and still below the 55 °C annealing step. That is a reason to look twice, not a predicted failure.
The code that produced the block above, as run:
import primer3
n1_f = "GACCCCAAAATCAGCGAAAT"
n1_r = "TCTGGTTACTGCCAGTTGAATCTG"
n1_p = "ACCCCGCATTACGTTTGGTGGACC"
# Primer3 defaults: 50 mM Na+, 1.5 mM Mg2+, 0.6 mM dNTP, 50 nM oligo
print(f"N1-F Tm at 50 nM : {primer3.calc_tm(n1_f):.1f} C")
print(f"N1-F Tm at 500 nM: {primer3.calc_tm(n1_f, dna_conc=500):.1f} C")
hp = primer3.calc_hairpin(n1_r)
print(f"N1-R hairpin Tm : {hp.tm:.1f} C")
for t in (25, 55):
d = primer3.calc_homodimer(n1_r, temp_c=t)
print(f"N1-R self-dimer dG at {t} C: {d.dg / 1000:.2f} kcal/mol")
res = primer3.design_primers(
{"SEQUENCE_PRIMER": n1_f, "SEQUENCE_PRIMER_REVCOMP": n1_r,
"SEQUENCE_INTERNAL_OLIGO": n1_p},
{"PRIMER_TASK": "check_primers", "PRIMER_PICK_INTERNAL_OLIGO": 1,
"PRIMER_EXPLAIN_FLAG": 1},
)
print("left :", res["PRIMER_LEFT_EXPLAIN"])
print("right:", res["PRIMER_RIGHT_EXPLAIN"])
alone = primer3.design_primers(
{"SEQUENCE_PRIMER_REVCOMP": n1_r},
{"PRIMER_TASK": "check_primers", "PRIMER_EXPLAIN_FLAG": 1,
"PRIMER_PICK_LEFT_PRIMER": 0},
)
print("N1-R alone:", alone["PRIMER_RIGHT_EXPLAIN"])
# The withdrawn N3 set: CDC traced its false positives to the
# 3' end of the probe pairing with the 3' end of the reverse primer.
n3_r = "TGTAGCACGATTGCAGCATTG"
n3_p = "ATCACATTGGCACCCGCAATCCTG"
het = primer3.calc_heterodimer(n3_r, n3_p, temp_c=25)
print(f"N3-R x N3-P dG at 25 C : {het.dg / 1000:.2f} kcal/mol")
for name, a, b in (("N3-R", n3_r, n3_p), ("N3-P", n3_p, n3_r)):
e = primer3.calc_end_stability(a, b, temp_c=25)
print(f"3' end of {name} on the other: {e.dg / 1000:.2f} kcal/mol")pip install primer3-py provides the primer3 module. If the import works in a terminal
and fails in Jupyter, the notebook is on a different interpreter. See
ModuleNotFoundError in Jupyter.
Finding 6: the same oligo has a 10 °C spread in Tm
The CDC instructions say the primers and probes were designed with melting temperatures above 60 °C, for a 55 °C annealing step. Calculators disagree depending on the inputs:
| Oligo | Primer3 defaults | Primer3, dna_conc = CDC reagent conc. | Same + 3 mM Mg²⁺ (assumed) | Biopython Tm_NN defaults |
|---|---|---|---|---|
| N1-F | 56.7 | 59.9 | 61.6 | 50.9 |
| N1-R | 60.8 | 63.6 | 65.3 | 54.9 |
| N1-P | 67.5 | 68.6 | 70.3 | 61.5 |
| N2-F | 57.1 | 60.4 | 62.1 | 51.3 |
| N2-R | 58.5 | 62.0 | 63.6 | 53.0 |
| N2-P | 66.4 | 67.6 | 69.3 | 60.5 |
| RP-F | 60.4 | 63.9 | 65.5 | 54.7 |
| RP-R | 62.4 | 65.7 | 67.4 | 56.6 |
| RP-P | 67.2 | 68.3 | 70.0 | 61.3 |
°C. The second column sets Primer3’s oligo concentration to CDC’s reagent concentration (500 nM primers, 125 nM probes). The third also assumes 3 mM Mg²⁺ and 0.8 mM dNTP. The CDC instructions do not give the master mix’s Mg²⁺ or salt, so that column is an assumption. Biopython’s defaults are 50 mM Na⁺, no Mg²⁺ and 25 nM of each strand.
Read the second column as sensitivity, not as a correction. The Primer3 manual describes its 50 nM default as the concentration of oligo annealing during PCR, lower than what goes into the tube. It says the default works well with a protocol using 0.5 µL of 20 µM primer in 20 µL, which is 500 nM. So Primer3’s own answer for these primers is the first column.
N1-F ranges from 50.9 °C to 61.6 °C across the four columns, and the sequence never changes. Only compare Tm values that came from the same tool with the same settings. To compare against a protocol’s stated Tm, you need to know how that protocol calculated it. The CDC instructions do not say.
Combining assays in one tube
The CDC instructions set up N1, N2 and RP as separate reactions, all read in FAM. If you multiplexed them with different dyes, the new risk is pairings between assays. There are 27. Under the consecutive model at 25 °C, one is flagged:
pair WC dG bp 3p verdict P3 dG P3end(a3p) P3end(b3p) WC stretch
N2-FxRP-R -6.94 5 no Check -9.99 1.29 -6.09 GCCGC (a 13-17) x b 3-7Primer3 scores the same pair at −9.99 kcal/mol, the most negative of all 27. At 55 °C the consecutive model flags none of the 27. This is a hypothetical: the panel was not designed for one well, and we did not run it that way. The point is the workflow: when you combine assays, score every cross pair, including probes, and test the top of that list first.
The workflow, as a checklist
- Confirm the sequences against the template. Exact match, expected strand, probe between the primers. A copy error makes every later number meaningless.
- Decide which tool’s numbers you will trust, and keep its settings fixed. Primer3’s defaults (50 mM Na⁺, 1.5 mM Mg²⁺, 0.6 mM dNTP, 50 nM annealing oligo) are a calibrated set. A ΔG or Tm cutoff only means something with the model and settings it was written for.
- Score hairpins, self-dimers and cross-dimers for every oligo in the tube, including probes, and across assays if you multiplex.
- Look at 3′ ends separately. A structure that pairs the 3′ end of a primer, on
another primer or on a probe, deserves attention even if its overall ΔG is moderate.
If your checker only scores unbroken runs, also run a mismatch-tolerant 3′-end check
such as Primer3’s
calc_end_stability, in both directions, and note whose 3′ end each score belongs to. - Score at 25 °C to find structures, then at the annealing temperature to judge whether raising the temperature could help. Don’t clear a structure only because it is weak at 55 °C.
- Treat all of this as a screen. The decision comes from the wet lab: no-template controls, a gel of the no-template product (the N2 report saw dimers below 50 bp), a melt curve for SYBR, and a dilution series for efficiency.
For a single pair, the primer dimer checker covers step 3. You can set ΔG temperature, Na⁺, Mg²⁺, dNTP and primer concentration on the page, and it marks whether a 3′ end is paired. Because it scores only unbroken runs, add the step 4 check from the code above for any primer–probe pair.
To prepare stocks of the primers you settle on, the
DNA concentration calculator
converts between ng/µL, nM and pmol for oligos. Our
DNA molecular weight tutorial shows why the common
330 × n shortcut for oligo molecular weight is off the most on short oligos.
What we did and did not verify
Ran:
- Sequence placement of all twelve oligos against MN908947.3 and NM_006413.5 (exact string match on both strands, both N3 probe variants).
- Tm with Primer3 under three settings and with Biopython.
- Hairpins for N1, N2 and RP with both models at 25 °C and 55 °C (default salt), and at 55 °C with the assumed 3 mM Mg²⁺ / 0.8 mM dNTP. No hairpin was flagged by the consecutive model in any of these.
- Self- and cross-dimers within each well, both models, at 25 °C and 55 °C (default salt), and at 55 °C with the assumed salt. Cross-assay pairs at 25 °C and 55 °C (default salt only). N3 pairs at 25 °C and 55 °C (default salt only).
- The rankings in Finding 2 (all 24 pairs, both directions), at 25 °C and default salt.
- The consecutive model against the four worked examples on the checker page, and against the live checker for N3-R × N3-P and N2-F × N2-P.
- Primer3
check_primerson N1, N2 and RP at defaults, and on N1 with the Tm floor and hairpin limit changed.
Did not do:
- No wet lab. We ran no PCR. The outcomes for N1, N2 and N3 come from the CDC and N2 reports cited above, not from our own experiments.
- The N2 outcome comes from one lab with its own reagents and a 60 °C annealing step, not CDC’s 55 °C. Other labs may not have seen it.
- The reaction buffer is an assumption. The CDC instructions name the master mixes but not their Mg²⁺ or salt.
- Two known failures are not a validation set. Finding 2 shows the ranking on this panel only.
- Neither model includes the dye or quencher chemistry.
- The full panel script is not published with this page. The code block above
reproduces the N1 and N3 numbers. The rest uses the same
primer3-pycalls.
Related
- DNA Molecular Weight in Python: A Runnable ng/µL → nM Workflow: for turning the primers you pick into accurate stock concentrations.
- A280 Protein Concentration Tutorial: ε280 for 11 Proteins: the same approach on the protein side, where the formula is easy and the inputs are where it goes wrong.
- ModuleNotFoundError in Jupyter: for when
import primer3works in a terminal and not in a notebook. - Tools: Primer dimer checker · GC content calculator · Reverse complement · DNA concentration calculator