Cross-posted from the github cutadapt page since there have been no responses from the author of cutadapt since November 2025.
I am working with paired-end ITS data and while I have no problem removing forward adapters, following the command from this link, no matter what I put for my reverse primer after the -A flag, I always get primers left over, whereas forward primers in fowrard reads and reverse primer in forward reads are successfully removed.
Here are my primers:
FWD <- "CTTGGTCATTTAGAGGAAGTAA"
REV <- "GCTGCGTTCTTCATCGATGC"
> FWD.orients <- allOrients(FWD); FWD.orients
Forward Complement Reverse RevComp
"CTTGGTCATTTAGAGGAAGTAA" "GAACCAGTAAATCTCCTTCATT" "AATGAAGGAGATTTACTGGTTC" "TTACTTCCTCTAAATGACCAAG"
> REV.orients <- allOrients(REV); REV.orients
Forward Complement Reverse RevComp
"GCTGCGTTCTTCATCGATGC" "CGACGCAAGAAGTAGCTACG" "CGTAGCTACTTCTTGCGTCG" "GCATCGATGAAGAACGCAGC"
During the cleaning, I found that my reverse primer is matching more to the reverse complement so in my command line code (I cannot get cutadapt to work in R) I use the following:
for r1 in *_R1.fastq; do r2=${r1/_R1.fastq/_R2.fastq}; sample=${r1%%_R1.fastq}; /home/chauk/.local/bin/cutadapt \
-a CTTGGTCATTTAGAGGAAGTAA...GCATCGATGAAGAACGCAGC -A GCTGCGTTCTTCATCGATGC...TTACTTCCTCTAAATGACCAAG \
-n 2 -o output2/${sample}_R1_cut.fastq -p output2/${sample}_R2_cut.fastq $r1 $r2; done
I have also tried other variations of primers but no matter what I always get the following output (example shown):
Forward Complement Reverse RevComp
FWD.ForwardReads 0 0 0 0
FWD.ReverseReads 1720 1715 1707 18415
REV.ForwardReads 0 0 0 0
REV.ReverseReads 20959 1826 1728 1744
I am clearly not using the correct primer order after the -A flag but I don't know what other combination I can even do to make this work.
Just for extra context, here are the primer counts before any filtering (not using filtN because I end up losing like 90% of my reads for all samples):
rbind(FWD.ForwardReads = sapply(FWD.orients, primerHits, fn = fnFs[[1]]),
FWD.ReverseReads = sapply(FWD.orients,primerHits, fn = fnRs[[1]]),
REV.ForwardReads = sapply(REV.orients, primerHits,fn = fnFs[[1]]),
REV.ReverseReads = sapply(REV.orients, primerHits, fn = fnRs[[1]]))
Forward Complement Reverse RevComp
FWD.ForwardReads 27211 0 0 0
FWD.ReverseReads 1720 1715 1707 18415
REV.ForwardReads 0 0 0 26660
REV.ReverseReads 26766 1826 1728 1744
Then I have decided to update my code to the following:
for r1 in *_R1.fastq; do r2=${r1/_R1.fastq/_R2.fastq}; sample=${r1%%_R1.fastq}; /home/chauk/.local/bin/cutadapt \
-g CTTGGTCATTTAGAGGAAGTAA -a GCATCGATGAAGAACGCAGC -G GCTGCGTTCTTCATCGATGC \
-A TTACTTCCTCTAAATGACCAAG -n 2 -o output2/${sample}_R1_cut.fastq -p output2/${sample}_R2_cut.fastq $r1 $r2; done
Which, when I check again for primers produces the following:
rbind(FWD.ForwardReads = sapply(FWD.orients, primerHits, fn = myfiles.For.cut[[1]]),
FWD.ReverseReads = sapply(FWD.orients,primerHits, fn = myfiles.Rev.cut[[1]]),
REV.ForwardReads = sapply(REV.orients, primerHits,fn = myfiles.For.cut[[1]]),
REV.ReverseReads = sapply(REV.orients, primerHits, fn = myfiles.Rev.cut[[1]]))
Forward Complement Reverse RevComp
FWD.ForwardReads 0 0 0 0
FWD.ReverseReads 1720 1715 1707 1518
REV.ForwardReads 0 0 0 0
REV.ReverseReads 1834 1826 1728 1744
So some primers are getting trimmed but it's not all 0's as is expected...
Also, I sometimes get the following warning (especially if I use the -g and -G flags instead of the linked adapters).
WARNING:
One or more of your adapter sequences may be incomplete.
Please see the detailed output above.
A final update which might complicate things. For some reason, the sequencing place used 4 ITS1 primers so while I have 4 potential ITS1 forward and reverse sequences, this still doesn't explain why I am able to trim all primers on forward reads with the primers I provided above. So it would seem to me, the forward reads were primed with the single primer set but somehow there are additional primers for reverse reads? This does not make sense to me but here are the additional sequences I could have for the forward and reverse ITS1 primers (all are TruSeq primers). I have just added stars around the primer sequences just to make it clearer (the astericks are not a part of the sequence):
Forward1 = ACACTCTTTCCCTACACGACGCTCTTCCGATCT**CTTGGTCATTTAGAGGAAGTAA**
Forward2 = ACACTCTTTCCCTACACGACGCTCTTCCGATCTT**CTTGGTCATTTAGAGGAAGTAA**
Forward3 = ACACTCTTTCCCTACACGACGCTCTTCCGATCTAC**CTTGGTCATTTAGAGGAAGTAA**
Forward4 = ACACTCTTTCCCTACACGACGCTCTTCCGATCTCAA**CTTGGTCATTTAGAGGAAGTAA**
Reverse1 = GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCT**GCTGCGTTCTTCATCGATGC**
Reverse2 = GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCTT**GCTGCGTTCTTCATCGATGC**
Reverse3 = GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCTAC**GCTGCGTTCTTCATCGATGC**
Reverse4 = GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCTCAT**GCTGCGTTCTTCATCGATGC**
1 answer
Your trimming actually worked. Look at which numbers moved: FWD RevComp in the reverse reads went 18415 -> 1518, and REV RevComp in the forward reads went 26660 -> 0. Those were the real read-through primers and they're gone.
The leftovers aren't primers. Notice they sit at roughly 1700-1800 in all four orientation columns, for both primers, and are essentially identical before and after trimming. That's the signature of N-matching rather than primer occurrence: primerHits in the DADA2 ITS tutorial calls vcountPattern with fixed = FALSE, so an N in a read matches any base in the pattern. One read with a run of Ns therefore registers as a hit for all four orientations of both primers at once, which is exactly the flat ~1700 you're seeing.
That's also why skipping filtN is biting you - the tutorial runs filterAndTrim with maxN=0 before the primer check for this specific reason. And losing 90% of reads at maxN=0 is the thing I'd actually chase, because that's a lot of Ns and it points at run quality rather than anything primer-related.
The four TruSeq variants are a red herring: with non-anchored -g/-G, cutadapt finds the biological primer regardless of the heterogeneity spacer sitting in front of it.
Log in to answer this question.