Octeth v5.9.4 Now Available! See What's New

Octeth v5.9.4: A Deliberately Boring Release, and Why That's the Point

Octeth v5.9.4 ships today with zero new features. It closes two vulnerabilities we found auditing our own code, and fixes a segment rule bug that could quietly sweep suppressed contacts into an audience. It's also the first release on our new two-week cadence — and a small, unglamorous release is exactly what that cadence is supposed to produce.

Octeth Team

Email Marketing Experts

7 min read
Octeth v5.9.4: A Deliberately Boring Release, and Why That's the Point

Octeth v5.9.4 is out today. It contains no new features.

Twenty-one commits, nine fixes, no database migrations. If you scanned the changelog looking for something to be excited about, you'd be done in about forty seconds.

I want to talk about why I think that's a good release, because two weeks ago I would have been embarrassed to publish it.

What Changed About How We Ship

Our last release, v5.9.3, took twenty-two days and contained 269 changes across 471 files. It was a good release. It was also too big, and it was too big for a specific reason: we were waiting for a list to empty before we'd ship.

That's a trap, and it's an easy one to fall into. You keep a milestone. Work goes into the milestone. You ship when the milestone is done. It sounds disciplined. In practice the milestone never empties, because new work arrives faster than you close it, so the release date drifts and the batch grows. By the time you finally ship, the risk isn't the number of open issues — it's the sheer surface area of everything you're changing at once.

So we changed the rule. Octeth now ships every two weeks, on the date, whatever is finished. The date is fixed. The scope is whatever made it in. Nothing gets held for a feature, and no release waits on a backlog.

v5.9.4 is the first release under that rule, and it produced exactly what it should have produced: something small, low-risk, and easy for you to evaluate. Fifty-three files instead of 471. No migrations. An upgrade you can reason about in an afternoon rather than schedule a weekend around.

A cadence that only ever produces exciting releases isn't a cadence. It's a marketing calendar.

We Audited Ourselves and Found Two Things

The substantive work in this release is security, and it came out of an internal audit rather than a report from outside.

We closed two vulnerabilities in the subscriber APIs that could allow an authenticated account on an installation to read data belonging to other accounts on the same installation. We found both while reviewing our own code, reproduced them under controlled conditions to confirm they were real rather than theoretical, and then verified the fixes by reverting the patch and re-running the same test. There's no indication either was ever exploited anywhere.

I'd rather say all of that plainly than describe it as "security enhancements."

Here's why this class of bug matters more for Octeth than it would for most software. A typical installation runs ten, thirty, sometimes fifty client accounts side by side on one platform. The wall between those accounts isn't a feature — it's the thing that lets an agency put its entire client book on a single installation. When we find a crack in that wall, the honest response is to fix it, tell you, and let you decide how quickly it needs to land on your servers.

And that last part is the bit I keep coming back to. Because you host Octeth yourself, you get to make that call. You know your risk profile, your change windows, and who has accounts on your install. A hosted platform would have patched this quietly and you'd have learned nothing. I don't think that's better. It's just quieter.

The Bug I'd Fix Even If It Weren't a Security Release

My favourite fix in this release isn't a vulnerability at all. It's a logic bug, and it's the kind that scares me more than most security issues do, because it fails silently and in the wrong direction.

Segments in Octeth are built from rules — conditions like "opened in the last 30 days" or "is not on the suppression list." Each condition maps to a piece of database logic. If a rule arrived carrying a condition the system didn't recognise — hand-built, imported, or malformed — it didn't refuse it. It fell through to a default. And the default it fell through to happened to be the logical opposite of what the rule said.

Think about what that means on a suppression rule. "Is suppressed" becomes "is not suppressed." A rule written specifically to keep addresses out of a send instead pulls them in.

Nothing errored. Nothing appeared in the interface. The segment produced a count, the campaign sent, and the numbers all looked plausible. That's the part that gets me: a crash is a gift, because somebody notices. A wrong answer that looks right can run for months.

An unrecognised condition now compiles to a rule that matches nobody, and writes to the log so somebody can find it. Failing closed on a suppression rule is the only defensible direction — the cost of sending to nobody is an awkward afternoon, and the cost of sending to a suppressed contact is a complaint, a deliverability hit, and in some jurisdictions a legal problem.

Segments built through the interface always carry valid conditions and were never affected. If you build or import rules directly, this one is worth the upgrade on its own.

Three More Silent Failures

There's a theme in the rest of the release, and it isn't an accident. Every remaining fix is a case where Octeth reported success while doing something other than what you asked.

Journey action saves could write to the wrong record when handed a stale reference, silently relocating child actions into branches that could never be reached. The save now verifies the record belongs to your account and the journey you're editing, and a failed save reports an error instead of appearing to work.

Email Gateway list sends stopped after the first 250 recipients — and returned a success response, with nothing to indicate the list had been truncated. If you've been sending to larger lists through the gateway and the numbers never quite matched, this is very likely why. There's now a setting that sends to the entire list; the previous behaviour stays the default so nobody's send volume changes overnight without them choosing it.

Email address searches using "contains" returned nothing at all for certain common search terms, rather than the matches that were sitting right there.

Silent failures are the worst category of bug in a platform like this, because your feedback loop is broken by definition. You can't act on information you were never given. Finding and removing them is unglamorous, it will never demo well, and I think it's a better use of a two-week cycle than another feature nobody asked for.

One Thing to Check If You Build Integrations

There's a single caller-visible change, and it's the sort of thing an integration can be quietly depending on.

A subscriber search called with an invalid search field used to return what looked like a successful search that simply matched nothing. It now returns an explicit error. If your code treats an empty result as "no matches," that's worth a look before you upgrade — an empty result and a rejected request should not look the same, which is precisely why we changed it.

We keep a page listing every deliberate behaviour change in a release, with a short checklist: v5.9.4 API behavior changes. The full changelog is here.

The Next One Is August 28th

That's the part I'm most interested in proving out. Not this release — the next six.

A two-week cadence is only worth anything if it holds when the work is unglamorous, when a cycle produces nothing you'd want to put in an announcement, and when shipping on the date means shipping something small. This release was all three, and it went out on schedule.

If you're already running Octeth, log in to the Octeth Client Area to download v5.9.4. Given the security fixes, I'd schedule it sooner rather than later — but you own the servers, so you own the timing.

If you're evaluating Octeth for your agency and want to see what running your own email infrastructure actually looks like, get in touch through the contact form. Happy to walk you through it, including the boring parts.

— Cem Hurturk

Share this article