Written and maintained by CASRAI Editorial Board
Last updated
Every alignment record in a SAM or BAM file carries a single integer in its second column: the FLAG field. That one number is not a single value in the ordinary sense — it is a bitwise combination of up to eleven independent yes/no properties of the read, packed into one field so the format stays fixed-width and fast to parse. A FLAG of 99 or 147 looks arbitrary until you unpack which bits are set. This guide covers the exact bit definitions from the SAM specification, how the bits combine arithmetically, worked decodes of three flags you will see constantly in real BAM files (99, 147, 2048), and the tools that decode flags correctly so you never have to do the bit arithmetic by hand.
What the FLAG field actually encodes
The SAM/BAM alignment format defines the FLAG field as a bitwise OR of the properties below, per the official SAM specification maintained by the samtools/hts-specs project. Each property occupies one bit, so each has a fixed decimal value equal to a power of two:
| Decimal | Hex | Meaning |
|---|---|---|
| 1 | 0x1 | Read is paired (part of a template with multiple segments in sequencing) |
| 2 | 0x2 | Read mapped in a proper pair (each segment aligned as the aligner expects) |
| 4 | 0x4 | Read unmapped |
| 8 | 0x8 | Mate (next segment in the template) unmapped |
| 16 | 0x10 | Read reverse strand (SEQ is reverse complemented) |
| 32 | 0x20 | Mate reverse strand |
| 64 | 0x40 | First segment in the template (read 1 of a pair) |
| 128 | 0x80 | Last segment in the template (read 2 of a pair) |
| 256 | 0x100 | Secondary alignment |
| 512 | 0x200 | Not passing filters, such as platform/vendor quality controls |
| 1024 | 0x400 | PCR or optical duplicate |
| 2048 | 0x800 | Supplementary alignment |
Two of these are worth distinguishing precisely, because they are frequently confused: a secondary alignment (256) is one of several equally-plausible mapping locations an aligner reports for the same read segment when it can’t pick a single best position; a supplementary alignment (2048) is a piece of a split/chimeric read — part of one read segment aligned to a different, non-adjacent location than the rest of it (structural-variant and fusion-transcript callers rely on these). They are not two names for the same thing, and a read can in principle carry either, both, or neither.
How the bits combine — and why the sum is always unique
Because every defined flag value is a distinct power of two, the FLAG integer is a straightforward sum: add up the decimal value of every property that’s true for that read, and the result is guaranteed to decompose back into exactly one set of bits. There is no ambiguity and no collision to worry about — two different combinations of properties can never produce the same FLAG integer, the same way two different sets of coins of denominations 1, 2, 4, 8… can never total the same amount. That’s the whole design rationale for using powers of two rather than, say, sequential integers.
Decoding a flag is the reverse operation: for each bit position, check whether that power of two is present in the number’s binary representation (a bitwise AND against the bit’s value). You can do this by hand for small numbers, but it stops being fast or safe to eyeball once several bits combine — which is why the tools section below matters more than memorizing the arithmetic.
Worked example: decoding FLAG 99
99 is one of the two flag values you’ll see on almost every properly-paired, uniquely-mapped short-read dataset — it’s the FLAG on read 1 of a pair. Decomposing 99 into powers of two: 99 = 64 + 32 + 2 + 1. Matching those against the bit table above:
- 1 — read is paired
- 2 — mapped in a proper pair
- 32 — mate is on the reverse strand
- 64 — this is the first segment in the template (read 1)
In plain language: this is read 1 of a properly-paired read, itself aligned to the forward strand (bit 16 is absent), whose mate aligns to the reverse strand. That forward/reverse orientation between mates is exactly what “properly paired” checks for in a typical paired-end short-read library.
Worked example: decoding FLAG 147
147 is the FLAG you’ll see on the mate of a 99 — read 2 of that same properly-paired fragment. 147 = 128 + 16 + 2 + 1:
- 1 — read is paired
- 2 — mapped in a proper pair
- 16 — this read itself is on the reverse strand
- 128 — this is the last segment in the template (read 2)
Notice the symmetry with the 99 example: where 99 carried “mate reverse strand” (32) because its mate was 147’s read, 147 carries “this read reverse strand” (16) directly, and “last segment” (128) instead of “first segment” (64). A 99/147 pair is the textbook signature of a correctly-oriented, properly-mapped paired-end fragment, and it’s worth recognizing on sight rather than re-decoding it every time.
Worked example: decoding FLAG 2048
2048 on its own decomposes to a single bit: 2048 — supplementary alignment, with every other bit unset (unpaired, not marked proper-pair, not marked reverse-strand, not marked duplicate, and so on). A bare 2048 is unusual in practice — supplementary alignment records for paired data more commonly show up combined with other bits, e.g. 2064 (2048 + 16: a supplementary alignment on the reverse strand) or with the pairing bits also set. The point of walking through the bare value first is that it isolates exactly what the 2048 bit itself asserts, before you meet it stacked with six or seven other bits in a real alignment: this record is one piece of a split alignment, and the aligner has designated a different record (elsewhere in the file, sharing the same QNAME) as the representative primary alignment for that read.
Tools for decoding flags — don’t do the bit arithmetic by hand
Manual decomposition is fine for a one-off explanation, but it’s the wrong workflow once you’re auditing real files, because it doesn’t scale and it’s easy to mis-add a bit. Two tools handle this correctly and are the standard practice:
samtools flags— a subcommand of samtools (part of the same htslib toolchain used to read/write BAM files) that converts between the numeric and textual flag representation in both directions. Runningsamtools flags 99prints the named properties that make up 99; running it with a comma-separated list of flag names does the reverse, returning the numeric value. This is the fastest path when you’re already at a terminal working with the file.- The Broad Institute’s online SAM flag decoder (explain-flags.html, part of the Picard documentation) — a browser-based decoder: type in a FLAG integer and it lists every property that’s set, or check boxes for the properties you want and it computes the resulting integer. Useful when you don’t have a terminal open, or when explaining a flag value to someone else and want the checkbox view rather than a wall of text.
Both tools implement the same bit table as the specification, so they will always agree with a correct manual decode — use them to check your own arithmetic, not as a black box you trust blindly.
Flag values you’ll encounter in practice
A handful of combinations recur constantly across aligner output. Recognizing them by sight saves a decode step:
| FLAG | What it usually means |
|---|---|
| 0 | Unpaired read, mapped, forward strand, no other bits set (common in single-end data) |
| 4 | Read unmapped — no alignment position; RNAME/POS/MAPQ are meaningless for this record |
| 16 | Unpaired read, mapped, reverse strand |
| 99 / 147 | A correctly-oriented, properly-paired read pair (read 1 / read 2) — see the worked examples above |
| 256 | Secondary alignment — an alternative mapping location for a read already reported elsewhere as primary |
| 1024 | Marked as a PCR or optical duplicate (typically set by a dedicated dedup step, not the aligner itself) |
| 2048 | Supplementary alignment — part of a split/chimeric read; see the worked example above |
Why this matters for downstream analysis
FLAG-based filtering is how most alignment QC and variant-calling pipelines decide which records to count. samtools view -f keeps only reads with the specified bits set; -F excludes them. A common pattern — keep primary, mapped, non-duplicate reads only — excludes bits 4 (unmapped), 256 (secondary), 1024 (duplicate) and 2048 (supplementary) in one pass (samtools view -F 0x904 ..., since 0x4 + 0x100 + 0x400 + 0x800 = 0x904). Getting this wrong is a real source of silently-biased results: counting secondary and supplementary alignments as if they were independent primary reads inflates apparent coverage depth without adding real information, and failing to exclude duplicates biases variant allele fractions upward. Whatever pipeline consumes the BAM downstream — alignment QC, variant calling, or coverage reporting — should document exactly which FLAG bits it filters on, since two pipelines that report “coverage” or “mapped reads” with different implicit FLAG filters are not comparable numbers.
The FLAG field sits alongside the other ten mandatory SAM columns covered in the BAM file format guide, and the format itself is one of three interoperable alignment container formats — see the SAM vs BAM vs CRAM comparison for how FLAG semantics carry over unchanged between them. Alignment indexing (covered in the BAM index (.bai) guide) also relies on FLAG-aware record handling for correct region queries. Upstream of alignment, the raw reads that eventually get a FLAG assigned come from a FASTQ file, whose per-base Phred quality scores influence which reads an aligner is confident enough to mark as properly paired in the first place.
Frequently asked questions
Is FLAG 0 a valid value?
Yes. FLAG 0 means every bit is unset: an unpaired, mapped, forward-strand primary alignment with no quality-control, duplicate, secondary, or supplementary markers. It’s common in single-end sequencing data and is not an error or a placeholder.
Can two different sets of read properties produce the same FLAG integer?
No. Because every defined bit value is a distinct power of two, the sum of any subset of them is unique — there is exactly one way to decompose a given FLAG integer back into its component bits. If two records show the same FLAG, they have identical values for all eleven properties.
What’s the difference between a secondary and a supplementary alignment?
A secondary alignment (bit 256) is an alternative reported mapping location for a read segment the aligner couldn’t place with full confidence at one position. A supplementary alignment (bit 2048) is a fragment of a split or chimeric read — part of the same read segment aligned to a different location than the rest of it, used for structural-variant and fusion detection. They describe different situations and a single record does not have to carry only one or the other.
How do I filter a BAM file by FLAG using samtools?
samtools view -f <FLAG> keeps only records with the given bit(s) set; samtools view -F <FLAG> excludes records with the given bit(s) set. Both accept a decimal or hex value and can be combined (e.g. -F 0x904 to drop unmapped, secondary, duplicate, and supplementary records in one filter).
Does the FLAG field mean anything different in BAM versus SAM?
No. BAM is the binary, compressed encoding of exactly the same eleven-bit FLAG field defined for SAM’s plain-text format — the bit definitions and their meanings are identical; only the on-disk representation differs.
Why does the mate’s strand (bit 32) matter if I already know my own read’s strand (bit 16)?
Because a proper pair is defined by the relative orientation of both reads, not either read alone. Bit 16 tells you this read’s own strand; bit 32 tells you the mate’s strand as recorded on this record (so you don’t have to look up the mate’s own alignment record just to check orientation). An aligner uses both together to decide whether to set the “properly paired” bit (2).








