← Septima blog

One flag, two incompatible brotli streams

2026-07-27 · engineering · substantially corrected 2026-07-31

Correction, 2026-07-31. This post originally ran under the title "The brotli archive that could only be opened on the machine that made it" and claimed such an archive needs the creating machine's core count passed back to open. That was wrong. Re-testing showed -mmt is a boolean mode switch on decode — the value is ignored, so any -mmt reads the stream and the archives are not machine-specific. The corrected mechanism is below; the upstream report has been corrected too. The failure mode is still real, just less dire — and considerably cheaper to work around.

Septima is a small thing: a GTK front-end that drives the 7zz binary from 7-Zip ZS. It doesn't reimplement compression — it builds the right command line and reads back what 7zz prints. That thinness is the whole design. It also means Septima inherits 7zz's sharp edges — and, if you're paying attention, catches them.

This is the story of one that would have quietly shipped unreadable archives to users, and how a single failing test caught it.

The trigger

In v0.3.0 we added Brotli, LZ4, LZ5 and Lizard as tar post-compressors — so you can make a real .tar.br in one gesture. Building the next feature (raw single-file streams), I wrote a round-trip test: compress a blob, extract it, assert the bytes come back identical. Every codec passed. Then brotli failed.

Isolating it

First guess: the compression level. I swept brotli levels 0–11 — all fine. So not the level. Same file, same everything, and yet the test built a .tar.br that 7zz itself refused to read:

7zz t out.tar.br
# ERROR: E_FAIL : Unspecified error

The difference between my passing manual test and the failing automated one turned out to be a single flag the app always added: -mmt (multithreading, set to the CPU count). Drop it, and the archive is fine. Add it — any value, even -mmt=1 — and 7zz can no longer read its own output.

It isn't corruption — it's two formats

"Unreadable" sounded like corruption, but the data was intact. -mmt selects between two different stream formats: the multithreaded chain, and plain brotli. Whichever one you wrote, you have to ask for the same one back.

The trap is that -mmt means opposite things on the two sides. On compress it's a thread count. On decompress it's a boolean format selector, and the number is ignored entirely:

# created with -mmt4
7zz t          mt4.br    # ERROR: E_FAIL
7zz t -mmt=1   mt4.br    # Everything is Ok
7zz t -mmt=2   mt4.br    # Everything is Ok
7zz t -mmt=32  mt4.br    # Everything is Ok

# created without -mmt
7zz t          st.br     # Everything is Ok
7zz t -mmt=1   st.br     # ERROR: E_FAIL

Stated plainly, with -mmt=off behaving like the default and -mmt=on like any -mmt=N:

decode flagmt streamplain stream
-mmt=off (or nothing)E_FAILOk
-mmt=on (or any N)OkE_FAIL

A stream created with -mmt12 extracts byte-identical using -mmt=2. So this is one bit of information — and brotli has no header block to record it in, which is exactly why 7zz can't just detect it. You get a bare E_FAIL with no hint that a flag would fix it.

The inversion. The behaviour flips by context. Brotli inside a 7z container (-m0=brotli) works fine with threads — so Septima's shipped 7z-brotli was never affected. It's only the standalone -tbrotli stream (which tar → brotli and raw .br both use) that splits into two formats. Same codec, opposite thread behaviour.

The fix, write side

A single-threaded standard .br is portable and reads anywhere — including with plain brotli, outside 7-Zip entirely. So the fix is to omit -mmt for the -tbrotli path, while keeping threads for 7z-container brotli, where they're both correct and useful:

// engine: build the -m* args
if let Some(threads) = self.threads {
    if self.format != "brotli" {      // the standalone -tbrotli case
        args.push(format!("-mmt={threads}"));
    }
}

Hunting it also surfaced a second, quieter bug from the same v0.3.0 work: the code that recognises "this is a compressed tar, browse inside it" had never learned .tar.br / .tar.lz5 / .tar.liz — so those archives, creatable since v0.3.0, couldn't be transparently opened. Fixed in the same pass.

The fix, read side

Not producing the trap is only half the job. Users open archives they didn't create — an mt-brotli .tar.br from a colleague, a script, or 7-Zip ZS on Windows. Septima passed no -mmt when extracting, so those failed with the same opaque E_FAIL.

Because there are exactly two modes and the value is irrelevant, the recovery is deterministic — no sniffing, no searching a space of thread counts, no heuristic that can be wrong:

// extract/test a brotli-family target
if run(args).failed_with_efail() {
    run(args + ["-mmt=on"]);   // flip to the other of the two formats
}

One retry, only on the failure path, only for brotli. That covers every mt-brotli stream in existence, whatever machine wrote it.

Why a thin wrapper earns its keep

It would be easy to dismiss "just shells out to 7zz" as barely a project. But the thinness is exactly why this got caught: Septima's job is to build correct command lines and verify what comes back, and its test suite round-trips real archives through the real binary. That's what turned a silent, flag-dependent failure into a red test on a Tuesday — before a single user made an unopenable .tar.br.

It's also why the correction at the top of this post exists. The first version of this write-up got the mechanism wrong in a way that sounded worse than reality, and the same wrong claim went upstream. Re-running the matrix — every decode flag against both stream types, extraction and not just t — is what settled it. Test the thing; don't reason about it from one data point.

Update, 10 August 2026: both fixes shipped in v0.4.0, along with the rest of the 7zz CLI-parity work — flatpak update if you're on the signed repo. Any .br or .tar.br written by v0.3.0 is still corrupt and can't be repaired; recreate those.

Upstream went further than the workaround described here. After testing the detection design on Linux and reporting a follow-on regression, 7-Zip ZS #538 settled on trying the single-threaded decode first and treating -mmt=off as the deliberate opt-in for the multithreaded format inside a .7z. Septima now retries with that flag on its own, so archives made elsewhere with raw brotli in a container open too.