Troubleshooting¶
This page covers these problems: an automatic truncation length that throws away
every read, a PhiX-removal step that stops on
the read pairs, a shotgun OTU table that comes out empty at a rank other than
species, a Bracken rank that MetaFlux refuses, a shotgun table step that stops on the
codes of the Kraken2 reports, a keep/discard token refused at start-up, a shotgun
taxon filter that removes every taxon, small differences between two runs on the same
data, a DADA2 error model that never converges, an outdated marker pack in
config/markers/, a reference file that fails the
reference check, a reference download that fails its md5 or SHA-256 check, and YAML
mistakes in the config. Each entry gives the symptom, the reason behind it, and what
to change.
Amplicon: automatic truncLen can drop all reads on very clean runs¶
Symptom
The run gets through primer trimming and QC, then stops at the DADA2
filtering step (rule dada_filter) with:
Cause. With amplicon.trunc_len.mode: auto, the pick_trunclen rule reads
the per-base quality tables that Falco wrote for the primer-trimmed reads
(stats/falco/{sample}_R{1,2}_stripped/fastqc_data.txt) and cuts just before the
first position whose per-base lower quartile (Q1, the 25th percentile of quality
at that cycle) falls below amplicon.trunc_len.q_threshold — 20 by default — so
the cut keeps the last cycle still at or above it. If quality never
drops that far, and clean MiSeq runs often stay high to the last cycle,
truncLen lands on the ceiling instead.
Falco reports a quality bin for every position up to the longest read in a file, however few reads reach it — so a ceiling taken from the quality table alone describes the longest reads, not typical ones. On a library where a few reads run to full length and most stop a little short, a cut placed there discards nearly everything.
MetaFlux guards against this by default: amplicon.trunc_len.min_read_coverage_pct
(95) caps each sample at the length that percentage of its reads still reach, before
quality is considered at all. The guard is on by default, so if this error appears
anyway, the cause is one of the two cases below.
After primer trimming most reads end a little before the full read length, and
DADA2's filterAndTrim discards any read shorter than truncLen rather than
padding it. So a cut placed at the very end of the read removes almost everything,
and DADA2 has nothing left to work with.
What it looks like on a real library without the guard
The 18S test dataset (PRJDB12231; see test datasets)
shows it. Its R1 quality never falls below Q20, so without the guard (MetaFlux
v2.1.0 and earlier) auto puts the R1 cut on the ceiling and returns
truncLen = 288 / 239. After primer trimming the reads themselves are:
| min | p05 | median | max | |
|---|---|---|---|---|
| R1 | 78 | 271 | 281 | 289 |
| R2 | 54 | 282 | 282 | 298 |
The ceiling comes out at 288 because the strictest sample sets it: its longest R1
read is 288 bp, while the other three reach 289. Most R1 reads (70%) stop at
exactly 281. Since filterAndTrim discards anything shorter than truncLen, only
9 of 908,768 pairs are long enough for the cut, and without the cap the run
finished with 3 ASVs.
Retention against the R1 cut, measured on this library:
| truncLen R1 | 288 | 281 | 275 | 270 |
|---|---|---|---|---|
| pairs retained | 0.0% | 70.3% | 92.4% | 100.0% |
Moving the R1 cut from 288 to 270 bp raises retention from 0% to 100%.
With the 95% read-coverage cap the R1 ceiling comes in at 271 instead of 288, and
auto returns 271 / 239 on this library with no manual intervention. It carries
90.9% of the raw reads through to the final table, practically the same as a
hand-picked 270 / 239.
Why it can still happen with the guard on. Two cases:
min_read_coverage_pctwas lowered. The value is a guarantee about reads, so a lower percentage permits a longer cut — that is the direction that reintroduces this failure, and it is the first thing to check. Raising it does the opposite, and100is not an off switch: it collapses the ceiling onto the single shortest read in the file, which fails the overlap constraint instead.- Read lengths are ragged enough that even the 95% length is unrepresentative.
Heavily pre-trimmed input does this, as do markers whose amplicons genuinely vary
in length.
logs/pick_trunclen.logtells you directly — it prints each sample's longest read alongside the length 95% of its reads reach, and emits aNOTEwhen the gap is 10 bp or more. A very large gap there means the ceiling is being set from a distribution with a long tail, and a hand-picked value will beat it.
Fix — set the truncation length by hand.
- Look at the read lengths after primer trimming: the
QC | primer-trimmed reads | {sample}_R{1,2}entries under "Sequence Length Distribution" in the MultiQC report, or the per-sample Falco reports understats/falco/{sample}_R{1,2}_stripped/. - Switch to
mode: manualand setmanual_r1/manual_r2a little below the length most reads still reach, sofilterAndTrimstops discarding them. - Keep the pairs long enough to still merge:
truncLen_R1 + truncLen_R2 ≥ amplicon_length + min_overlap(amplicon.min_overlapis 12 bp by default).
Pick the R1 and R2 cuts separately
Only the read whose quality stayed flat is stuck on the ceiling. In the example
above R2 did degrade, so auto found a quality-based cut for it at 239. Only R1
needed a new value; R2 kept the cut that auto found.
Retrying is cheap
Snakemake picks up where the run left off: PhiX removal, primer trimming and QC are already done and stay done, so only DADA2 and the steps after it run again. Trying a second value costs minutes, not a full re-run.
ITS is not affected
For type: ITS, dada_filter overrides truncLen to c(0, 0)
unconditionally — ITS amplicons vary in length, so a fixed cut would throw
away genuinely short sequences. The 3′ tail is still cleaned, by truncQ
and maxEE instead. Because the override is unconditional, manual_r1 /
manual_r2 have no effect on an ITS run either.
Background on how the cut is chosen, and on the overlap constraint, is in Amplicon length and truncation.
Shotgun: BBDuk PhiX removal stops on the read pairs¶
Symptom
The shotgun run aborts at rule decontam_phix with one of these two messages:
java.lang.AssertionError:
There appear to be different numbers of reads in the paired input files.
The pairing may have been corrupted by an upstream process. It may be fixable by running repair.sh.
The first means the pairing is broken. The second does not: it comes from a newer bbmap than the one MetaFlux pins (see the end of this entry).
Cause. BBDuk reads the R1 and R2 files in lockstep, one record from each at
a time, and requires both files to hold the same number of records in the same
order. Read length has nothing to do with it — ragged lengths, and mates of the
same pair ending up different lengths, are processed normally. "There appear to be
different numbers of reads" means R1 and R2 contain different numbers of reads,
which usually happens when reads were filtered before deposition and orphaned mates
were left behind in one file. SRA and BioProject submissions are the common
case. MetaFlux's own fetch can produce it as well: rule download_sra calls
fasterq-dump --split-files, which writes a record to _1 only for any spot
holding a single read (--split-3 is the option that keeps the two files in
step).
The BBMap host-removal step (rule decontam_host) fails on the same input, for
the same reason and with the same message: BBMap reads the pair in lockstep too and
makes the same requirement. The message names the fix outright.
Fix — repair the pairing. repair.sh ships in the same bbmap conda
package MetaFlux already installs for these rules, so no extra tool is needed:
repair.sh in1=R1.fastq.gz in2=R2.fastq.gz \
out1=fixed_R1.fastq.gz out2=fixed_R2.fastq.gz \
outs=singletons.fastq.gz
It re-syncs the two files on read name and writes the leftover single-ended
reads to outs=. Point input.fastq_dir at the repaired files and run again.
Where the raw, untrimmed reads are still available they are the better starting
point: they are properly paired, and MetaFlux trims with fastp anyway, so
pre-trimmed input buys nothing.
remove_phix: false is not a fix here
Switching PhiX removal off only moves the failure to BBMap, which stops on the same files. Switching host removal off as well moves it to fastp, which stops on unequal record counts too. Repair the files instead.
List size mismatch is a different problem. MetaFlux pins bbmap 39.52, whose
BBDuk and BBMap never print this message. It comes from the rewritten BBDuk that
bbduk.sh runs in bbmap 39.76 to 40.02: its paired-read reader loses track of
mates and stops with this message, or hangs, on correctly paired reads, above all on
trimmed reads whose mates differ in length. It prints the same message on broken
pairs too, so it says nothing about the pairing, and repair.sh does not help. The
first lines of logs/decontam_phix/{sample}.log name the version that ran
(Version 39.52 for the pinned one).
Fix — run with MetaFlux's environment. Start the run with --sdm conda, so that
Snakemake installs and uses the pinned environment (workflow/envs/bbtools.yaml),
and keep the pin if you edit that file. MetaFlux before v2.5.0 did not pin bbmap, so
its environment could get one of these releases.
More on host references and masking is in Decontamination.
Shotgun: empty or nearly empty OTU table with tax_lev other than S¶
Symptom
shotgun.bracken.tax_lev is set to G, or to any rank other than S. The run
finishes without an error, but 03.abundance/otu_table.tsv has no rows, or only a
handful, while Bracken's own {sample}_output.txt files list plenty of taxa.
Cause. Fixed in v2.5.0. Up to v2.4.0, rule kraken_biom ran kraken-biom with its
default settings, which assume a species-level report: it takes the clade count for
species, and from genus up to order only the reads placed directly on the taxon.
Plain Bracken 3.1 writes 0 in that column for almost every taxon above species (a bug
in Bracken itself, fixed in the 3.1p1 build that MetaFlux pins from v2.5.0 on), so
those taxa dropped out. A genus survived only when Kraken2 had placed no reads on any
of its species, and at class, phylum or domain level, which lie outside that range,
nothing survived at all. Bracken's {sample}_output.txt files were never affected, and
neither were species-level runs.
Fix. Update to v2.5.0 or later and run the same command again, from the same
MetaFlux folder. From v2.5.0 on, MetaFlux builds the table with rule
finalize_otu_table straight from the Bracken reports, from their clade counts, and
pins Bracken 3.1p1. In a folder made with an earlier version every step runs again,
Kraken2 included, because the output folders have new names (see
What happens on a re-run), so nothing
has to be forced.
A config with tax_lev: D stops at start-up from v2.5.0 on; see the next entry.
Shotgun: the run refuses tax_lev: D or K¶
Symptom
A run with Kraken2 (profiler: kraken2 or both) stops before any step starts,
with one of these messages (wrapped here):
[MetaFlux] shotgun.bracken.tax_lev: D is not allowed. Viruses have no domain in
NCBI's taxonomy (since 2025), and at this rank Bracken adds their reads, with a
share of the reads left at the root, to the domain the Kraken2 report lists last
(usually Archaea). Use P or a lower rank. To compare domains, add up the rows of
otu_table.tsv by their d__ slot; that sum counts the reads Bracken placed at the
table's rank, not every read of the domain.
[MetaFlux] shotgun.bracken.tax_lev: K is not allowed. Most protists have no
kingdom, and a GTDB database has no kingdom rank at all. At this rank Bracken adds
the reads of a taxon without a kingdom to the kingdom the Kraken2 report lists just
before it, and on a GTDB database it stops after Kraken2. Use P or a lower rank;
the k__ slot of otu_table.tsv gives the kingdom of each row.
Cause. Bracken reads a Kraken2 report from top to bottom and adds the reads of every row below the target rank to the last row of that rank it has read. For a taxon that has the target rank, that last row is the taxon's own ancestor, because the report lists every branch right after its parent. A taxon without the rank is counted towards whichever row of that rank comes before it. At domain and kingdom level whole groups of taxa lack the rank:
- Domain. Viruses have no domain in NCBI's taxonomy since 2025, and their branch
comes after all cellular organisms. Their reads, and the share of the root's reads
that Bracken attributes to them, go to the domain listed last. Kraken2 lists sister
rows by read count, largest first, so this is the domain with the fewest reads,
usually Archaea. In a saltmarsh rhizosphere sample (SRR6394731, BioProject
PRJNA422917) classified with the Kraken2 index
k2_NCBI_reference_20251007, Archaea had 2,612 reads at phylum level and 35,636 at domain level, from only 71 viral reads and the root reads attributed to them. - Kingdom. Most protists have no kingdom in NCBI's taxonomy, and GTDB has no kingdom rank at all. The protists' reads go to the kingdom listed just before them: in the same rhizosphere sample, Fungi had 7,957 reads in its phyla but 12,001 at kingdom level. On a GTDB database Bracken finds no kingdom and stops with "no reads found", after Kraken2 has run.
Fix. Set tax_lev to S, the default. It is the only rank where this cannot
happen, because every row below a species row is a strain of that species. At P to
G it hits only the few taxa that lack that rank, but one row can still gain several
times its own reads: in the rhizosphere sample, protists without a phylum took
Oomycota from 56 to 1,095 reads at P, and bacteria without an order took Nevskiales
from 1,393 to 6,237 at O. At these ranks, compare a surprising row with the
species-level table.
Domain and kingdom totals can be read from any of these tables: add up the rows of
otu_table.tsv by their d__ or k__ slot. That sum counts the reads Bracken placed
at the table's rank, not every read of the domain or kingdom: reads that Kraken2 left
above that rank, and that Bracken could not push down, are in no row (see
Bracken abundance re-estimation).
With profiler: sylph Bracken does not run, and tax_lev is not checked.
Shotgun: the table step stops on a report code¶
Symptom
The run stops at rule finalize_otu_table with a message like this one (wrapped
here):
[finalize_otu_table] SRR123_report.txt: Eukaryota (taxid 2759) is a domain in the
Kraken2 database set as references.kraken_db, but the report codes it R2, not D.
Kraken2 releases before 2.17 write reports like this (they do not know the rank name
'domain'), and so do reports made with another database. Run Kraken2 again on
references.kraken_db with the release MetaFlux pins (workflow/envs/kraken2.yaml), for
example with -R kraken2.
Its relatives say that a taxon "is coded D, but it is not a domain", that a kingdom is
not coded K (or a K row is not a kingdom), or that one taxon "has two lineages".
No table is written.
Cause. The OTU table takes its domain and kingdom slots from the rank codes of the
Bracken reports, and MetaFlux checks every D and K code against the taxonomy of the
database named in references.kraken_db, its taxo.k2d file. The two disagree when the
Kraken2 reports were written by a Kraken2 older than 2.17, which codes NCBI's domains
R1 or R2 (a run started without --sdm conda uses whatever Kraken2 is on the
PATH), or when they were made with another database than the one the config names
now. Reports of two databases can also give one taxon two lineages. A table built from
such reports would have an empty d__ slot in every row, or slots filled from another
taxonomy, with no other sign that anything is wrong.
Fix. Run Kraken2 again with MetaFlux's pinned environment (--sdm conda), against
the database the config names; -R kraken2 forces it when Snakemake sees nothing to
redo. If instead the reports are right and the config names the wrong database, point
references.kraken_db back at the database they were made with.
Start-up: the run refuses a keep/discard token¶
Symptom
The run stops before any step starts, with a message like this one (an amplicon
run; in a shotgun run the message names shotgun.taxonomy_filter and the Kraken2
database):
[MetaFlux] these amplicon.taxonomy.filter tokens can never match a taxonomy string of this run (16S, method sintax, release 144), so the run stops before any step:
- amplicon.taxonomy.filter.keep: 'k__Bacteria' puts a domain under k__, which holds kingdoms in this table. Bacteria is a domain: write d__Bacteria.
- amplicon.taxonomy.filter.keep: 'k__Archaea' puts a domain under k__, which holds kingdoms in this table. Archaea is a domain: write d__Archaea.
A token must equal one whole slot of the taxonomy string, prefix included. Since v2.5.0 the domain is always written d__, and k__ is the kingdom where the reference has one.
Cause. The taxon filter compares each token with whole slots of the taxonomy
strings, so a token that no string of the run can contain would remove every ASV or
taxon in keep, or nothing in discard, and the run would only find out at its end.
MetaFlux therefore checks the tokens when it starts, also with the filter switched off.
The usual cause is a config written for MetaFlux v2.4.0 or earlier, which wrote the
domain under k__ (k__Bacteria); since v2.5.0 d__ is always the domain and k__
always the kingdom. The message names the other causes too: a prefix the marker, method
or SILVA release never writes (k__ on SILVA 138.2 or rpoB, d__ on ITS, s__ on 16S
under sintax), a name that cannot stand in that slot of the reference (k__Fungi on
16S), and in a shotgun run Viruses, or a virus realm under k__.
Fix. Write the token the message names (d__Bacteria for k__Bacteria) and run the
same command again; nothing has run yet, so nothing is lost. The rules, and what the
check cannot see, are under
when MetaFlux refuses a token at start-up.
Shotgun: the taxon filter removed every taxon¶
Symptom
The run stops at rule finalize_otu_table with a message like this one (wrapped
here; the numbers depend on the run):
[finalize_otu_table] shotgun.taxonomy_filter removed every taxon of the table
(111 taxa; keep: [p__Firmicutes], discard: []). The d__ values in this table are:
d__Archaea (1 taxon), d__Bacteria (107 taxa), d__Eukaryota (3 taxa). A token must
equal one whole slot of the lineage, prefix included (d__ k__ p__ c__ o__ f__ g__
s__). Check the tokens, or set shotgun.taxonomy_filter.enabled: false.
No otu_table.tsv or otu_table.biom is written.
Cause. shotgun.taxonomy_filter compares each token with whole slots of the
lineage, so a token with a name the table does not have matches nothing. A keep list
in which no token matches removes every row, and so does a discard list that covers
every row. An empty table would look like a finished run, so MetaFlux stops instead, as
the amplicon filter does. Tokens that can never match any table (a wrong prefix, a
domain under k__) stop the run at start-up already (see
the entry above), but names below the
kingdom are not checked there, so a misspelt name, or one the database does not use,
gets this far: NCBI's taxonomy names the phylum p__Bacillota, not p__Firmicutes.
Fix. Compare the tokens with the d__ values the message lists, or with the
taxonomy column of a run made with shotgun.taxonomy_filter.enabled: false, correct
them and run the same command again. Kraken2 and Bracken do not run again; the table is
built again from the Bracken reports already in 03.abundance/. To keep every taxon,
switch the filter off.
Amplicon: ASV counts or taxonomy calls differ between identical re-runs¶
Three steps in the amplicon path draw on a random-number generator, so two runs on the exact same input can differ slightly:
| Step | Rule | What the random draw is for |
|---|---|---|
DADA2 learnErrors(randomize = TRUE) |
dada_seqtab |
Subsamples reads to build the error model |
DADA2 assignTaxonomy (method: rdp) |
assign_taxonomy |
Bootstrap confidence |
VSEARCH --sintax (method: sintax) |
assign_taxonomy |
Bootstrap confidence, seeded from a random source by default |
Without a fixed seed each of these draws a different sample every run, so a handful of ASVs or taxonomy calls sitting near a decision threshold can flip between two runs. This is expected DADA2/VSEARCH behaviour — not a bug, and not corrupted data.
Before v2.4.0 the order of the reads also differed between runs, and the seed had no
effect on it: bowtie2 removed phiX on several threads and wrote the surviving pairs in
whatever order they finished, so every run
handed DADA2 the same reads in a different sequence (pairing was never broken, and
cutadapt and filterAndTrim only drop reads, they never reorder). DADA2 numbers ASVs by
decreasing abundance and keeps the input order for ties, so two ASVs with exactly the
same total count could swap IDs between runs. Fixed in v2.4.0: bowtie2 now runs with
--reorder, so every run hands DADA2 the reads in the same order and gets the same ASV
sequences and counts back. If you are reading output from an earlier version, compare
runs by sequence rather than by ASV ID. See
Reproducibility for what this meant for the
optional phylogeny stage, which is sensitive to the order of the alignment rows.
amplicon.seed (42 by default) fixes the generator for all three, and the thread count
then no longer changes the result:
learnErrors: reproducible at any thread count.--sintax: reproducible at any thread count, from v2.5.0 on. MetaFlux v2.5.0 runs VSEARCH 2.32, which gives every ASV its own random stream. Older VSEARCH releases shared one stream between all threads, so up to v2.4.0 thesintaxresults were identical only on one thread (resources.threads.assign_taxonomy: 1). A new VSEARCH release can also draw differently, as 2.32 did, so compared with a run made with an older MetaFlux version many confidence values move slightly, and a lineage near the cutoff can gain or lose a trailing rank, even with the same seed. The raw_sintax_raw.tsvlists the ASVs in the order the threads finish them, so sort it before comparing two runs; the tables built from it do not depend on that order. All of this needs a positiveamplicon.seed: VSEARCH reads0as "pick a random seed".assignTaxonomy(rdp): reproducible at any thread count, with one exception. DADA2'sassignTaxonomybreaks exact ties between equally good reference lineages at random, outside the seed, so a few bootstrap values can differ between identical runs;sintax, the default, is not affected. Now and then such a tie flips an ASV's whole lineage between two identical runs, even its kingdom: on the ITS test set (PRJNA862334), ASV_16 had an orchid as best hit in 8 of 11 identical runs and Saccharomyces in the other 3. Its kingdom support reachedmin_boot: 80in only one of those three, sokeep: [k__Fungi]kept the ASV in 1 run and removed it in the other 10.
Amplicon: DADA2's error model never converges¶
Symptom
Rule dada_seqtab runs for hours. Its log (logs/dada_seqtab.log in the output
directory) keeps adding selfConsist step lines and never reaches the
Convergence after N rounds. line that normally follows them:
[dada_seqtab] Learning error rates (R1, nbases=1e+08)...
396568980 total bases in 1468774 reads from 1 samples will be used for learning the error rates.
selfConsist step 1 .
selfConsist step 2
selfConsist step 3
...
selfConsist step 172
On the COI mock libraries the marker was validated on, each model converged in 4 to
32 rounds and dada_seqtab took 5 to 23 minutes.
Cause. DADA2's learnErrors fits one error model per read file: for every quality
score, how often each base is read as another base. It assumes that every read in the
file was produced the same way, and it repeats two steps, denoising the reads with the
current error rates and estimating the rates again from the result, until a round gives
exactly the same error table as an earlier round. A file whose reads do not share one
error profile can keep the estimate moving. Three ways that happens:
- Reads of both strands in one file. When some reads are reverse complements of the others, the sequencer's errors appear mirrored in part of the file (a true A read as G in the forward reads is a T read as C in the reversed ones), and the poor bases of the reversed reads sit at the start of the read instead of the end, where no truncation removes them.
- Reads that still carry primer bases. A primer with degenerate positions leaves the reads of one template differing from each other at several positions of high quality, which to DADA2 look either like real variants or like errors at a quality score that should hardly have any.
- A folder trimmed under
orientation: mixedby MetaFlux v2.5.0 or earlier, which has both problems at once: the old second pass reverse-complemented the reversed pairs instead of swapping their mates, and the first pass also kept, through a chance match of three primer bases, pairs that were the other way round with most of a primer still on.
Measured on a genuinely mixed COI library (two libraries of the same insect mock in
opposite orientations, 1.6 million pairs as one sample) trimmed the old way: of the R1
reads DADA2 learned from, half were reverse-complemented, with their quality running
backwards, and 7 % still began with 17 bases of the primer; the R1 model had not
converged after 171 rounds and 10.5 hours when the run was stopped. The same pairs
trimmed with v2.6.0 converged in 6 and 5 rounds. pick_trunclen had shown the problem
first: with the poor last bases of the reversed reads now at the start of the read, the
lower quartile of the quality is below the Q20 threshold at the very first cycle (18 in
R1; 16 and 18 in the first two cycles of R2) and at or above it afterwards, and
pick_trunclen cuts before the first cycle that fails, so the quality-based cut lands at
0 (Primary cuts at Q1>=20.0: R1=0, R2=0 and WARNING: very short primary cuts in
logs/pick_trunclen.log) and the truncation lengths come from raise_trunc alone
(270 / 160 here).
MetaFlux sets amplicon.dada2.learn_errors.max_consist to 999, so the job runs on until
the model converges, someone stops it, or it reaches round 999; at 3.7 minutes a round,
as on this library, that is about 60 hours for the R1 model alone. At the limit DADA2
prints Self-consistency loop terminated before convergence. and continues with the last
estimate, as it does after its own default of 10 rounds, and the run finishes, with a
model fitted to a mixture and tables made from it.
Fix. Stop the run and check the trimmed reads before the error model. In
03.stripped/{sample}_R1.fastq.gz every read should start with the first bases after the
forward primer, and the quality of a read should fall towards its end, not rise; a read
that starts with the primer itself, or with the last bases of the other primer, was not
trimmed cleanly. With orientation: mixed, stats/orientation/{sample}.tsv says how
many pairs each pass kept; a folder trimmed by MetaFlux v2.5.0 or earlier has no such
file, and a run with v2.6.0 trims it again, with everything after it (see
the mixed-orientation second pass).
If the reads were trimmed before MetaFlux saw them, or the two files of a sample are
swapped, correct the input: a library in which every pair is swapped is run with its two
files swapped and orientation: fixed, a library with pairs in both orientations with
mixed.
Amplicon: an outdated marker pack in config/markers/ stops the run¶
Symptom
Every amplicon run stops before any step starts, whichever marker it uses, with:
Cause. A pack in config/markers/ replaces the shipped pack of the same name
completely, so an old copy would bring back everything the shipped pack has changed
since: an 18S pack from MetaFlux v2.4.0 would classify against PR2's own letter order,
which hides the domain of many ASVs. Since v2.5.0 every pack declares
reference_values, the rules its reference file is checked against before
classification, so a pack without them was written for an older MetaFlux. Every pack in
config/markers/ is checked on every amplicon run, which is why an outdated 18S pack
stops a 16S run too. A pack for a marker of your own without reference_values gets a
message of its own, which says what to add.
Fix. Copy the shipped pack (workflow/markers/<marker>.yaml) to config/markers/
again and re-apply your change, or delete the copy if the shipped pack now does what
you need. For a marker of your own, add reference_values with rules for its top
ranks, or reference_values: {} to have only the rank shape checked (see
the reference check).
An 18S pack that does declare reference_values but keeps PR2's original SINTAX
letters (k, d, p, …) stops under method: sintax with a message about VSEARCH's
fixed letter order; the fix is the same.
Amplicon: the reference check stops the run¶
Symptom
The run stops at rule check_taxonomy_reference, before any classification, with
a message like this one (shortened):
[check_taxonomy_reference] /shared/dbs/silva_nr99_v144_toGenus_7rank_other-verbatim_trainset.fa.gz does not hold the ranks declared by the 16S marker pack, release 138.2, method rdp (Domain, Phylum, Class, Order, Family, Genus, Species):
- a lineage deeper than the 6 ranks the rank model expects in this file (the Species rank comes from addSpecies): 473,550 header(s)
e.g. >Bacteria;Pseudomonadati;Pseudomonadota;Gammaproteobacteria;Pseudomonadales;Pseudomonadaceae;Pseudomonas;
- the deepest lineage has 7 ranks, but the rank model expects 6 in this file (the Species rank comes from addSpecies)
The classifier would put names on the wrong ranks, so the run stops before any classification. Either the run config points at a wrong file (references:, and for 16S the SILVA release chosen with references.silva.release), or the reference changed upstream and its marker pack needs a new release block (see the reference_values notes in workflow/markers/16S.yaml).
Cause. A classifier never checks what a rank means: if a reference has one rank more
or less than the marker pack expects, or two ranks swapped, every name lands in the
wrong column and nothing errors. So before any classification MetaFlux checks the exact
file the classifier is about to read against the rank set and the names its pack
declares (see
the reference check).
The message names the file, what does not fit, and example headers. Almost always a path
under references: points at the wrong file: in the example, a SILVA 144 training set
(seven ranks, with the kingdom) pinned as silva.train for a run on SILVA 138.2 (six
ranks). Less often the reference itself has changed upstream.
Fix. Point the references: entry at the file that belongs to the run's marker and
SILVA release, or remove it, so that MetaFlux uses, and if needed builds, its own (see
reference files MetaFlux builds itself).
For 16S, keep references.silva.release and the pinned SILVA files together. If the
reference itself has changed (a new release with another rank), the marker pack needs a
new release block. logs/refdb/check_taxonomy_reference.log in the output directory
lists every problem the check found.
Amplicon: a reference download stops with "md5 mismatch"¶
Symptom
A fetch_* rule fails, and its log (logs/refdb/fetch_<name>.log in the output
directory) ends with one of these lines (the second comes from the COI downloads,
whose MIDORI2 FASTA and bacterial reference files are checked against SHA-256 sums):
Cause. The downloaded file is not the one the marker pack expects: the download was cut off, a proxy returned an error page, or the file behind the address has changed. MetaFlux deletes the file, so it is never used.
Fix. Run the same command again; a broken download usually works the second time. If the same checksum comes back every time, the file on the server has changed. Report it as an issue on GitHub rather than editing the md5 or SHA-256 in the marker pack.
Config (YAML) errors¶
Snakemake reports any config problem with one generic message ("Config file is not valid JSON or YAML…"). That almost always means a YAML indentation or list-syntax issue, or a stray tab — not a problem with the parameter values themselves. Validate the file directly to get the exact line:
A "expected block end, but found block sequence start" message points to a
misplaced or over-indented - list item — commonly in host_genomes.
The full key-by-key reference is in Configuration.