“why not matrix?” is a numbered list of twenty-one objections to the Matrix protocol, written by a pseudonymous author, haru, who describes having studied Matrix since 2021 and evaluated Conduit and Dendrite alongside the flagship Synapse. The argument is architectural rather than implementation-specific: a Matrix room is a partially replicated, append-only DAG of cryptographically signed events, and most of the failures the article lists are presented as consequences of that data model rather than as bugs awaiting a patch.
The text dates from 2023
The republication matters because the article reads as current and is written in the present tense throughout. Nothing on the page marks it as an archival copy, notes an original publication date, or flags the intervening spec releases. A reader who takes the masthead date at face value inherits a three-year-old assessment of an actively revised protocol.
What the article argues
The objections fall into five groups.
| Group | Items | Core claim |
|---|---|---|
| Permanence | 1–4 | The graph is append-only; redactions are advisory and can leak later; membership and power events are welded into the auth chain and can never be removed |
| Ordering | 5–7 | Room history is hard to linearize, depth and origin_server_ts are forgeable, and events can be inserted into the past |
| Encryption | 8–10 | E2EE is optional and client-enforced, breaks when device-list updates fail to sync, and those updates leak client and platform information |
| Consensus | 11–16 | JSON canonicalization diverges between implementations, signing-key expiry is attacker-controlled, and state resolution produces state resets that strip administrators of power |
| Hosting | 17–21 | Rooms cannot be shut down federation-wide, moderation depends on the auth system it can break, and the media repository replicates unverified content a server may become liable for |
The permanence group carries the argument. Everything downstream of it — the moderation failures, the liability exposure, the inability to retract — follows from the claim that a federated append-only graph gives no participant the power to make another participant forget.
What has been superseded
Three claim families were current in 2023 and are no longer accurate descriptions of the protocol.
| Article’s claim | Status as of August 2026 |
|---|---|
| Media downloads are “unauthenticated by default” (items 19–21) | Superseded. MSC3916 shipped in Matrix 1.11 on 20 June 2024, deprecating the /_matrix/media/* endpoints; Synapse 1.120 flipped enable_authenticated_media to true on 26 November 2024, and the flag was removed entirely in July 20252 |
| State resets have “no solution in sight” (item 14) | Superseded. State Resolution v2.1 shipped in room version 12 in September 2025, eleven months before republication3 |
| Administrators lose power over rooms through state resets (item 16) | Addressed. Room version 12 gives room creators an infinite power level that cannot be set in m.room.power_levels or changed after creation3 |
| The spec “doesn’t actually define what the canonical json form is strictly” (item 11) | Wrong when written. The specification defines Canonical JSON precisely, with an ABNF grammar and a reference implementation, and had done so since November 20214 |
The canonical-JSON item is the weakest,
and it is worth separating from the interoperability claim that follows it.
The spec fixes the encoding exactly:
shortest UTF-8 form, keys sorted lexicographically by Unicode codepoint,
integers confined to [-(2**53)+1, (2**53)-1],
no exponents, decimals, floats, or negative zero.
Item 12’s separate observation —
that homeservers written in different languages
have produced mismatched signatures in practice —
is an implementation-divergence claim
the spec’s own text partly concedes,
since it warns that events in room versions 1 through 5
may not comply with those restrictions.
The article presents the second as evidence for the first.
The residue on media is narrower than the article but has not disappeared: media stored before a server enforced authentication remains reachable on the legacy endpoints indefinitely, a deliberate backwards-compatibility choice.2
What still stands
The permanence group survives intact, because it describes properties of the data model rather than defects in an algorithm. No spec revision has made redactions binding on a server that declines to honor them, removed membership and power events from the auth chain, or given any participant the power to shut a room down across the federation. This is Advisory deletion in its sharpest form: the same limit the wiki records for Nostr, ActivityPub, AT Protocol, and Secure Scuttlebutt, reached here by a system that most of its users believe they are using as a chat app.
State resolution is improved rather than solved. MSC4297 says so directly: more changes are required to fix all cases of state resets, and Project Hydra continues.3
Reading this as evidence
The article is a practitioner’s assessment, not a security analysis. It is pseudonymous, self-published, and carries no citations, so each claim has to be checked against the specification or an issue tracker before a note relies on it. It has no comment facility, which is why the substantive 2023 replies — including one from Matrix’s project lead — live on Lobsters rather than beside the text.1
Its value is the inventory rather than the verdict. Assembling the consequences of an append-only replicated graph into one list is useful work, and the permanence items are accurate and well-posed. The verdict they support is weaker than the article states, partly because two of its sharpest items were already stale when the list was republished, and partly because it never weighs the properties the same architecture buys: no operator can unilaterally erase a room’s history either, which is the same fact viewed from the other side.
-
why not matrix? (haru, Telegraph, 7 August 2023) is the original publication. The Lobsters thread (7 September 2023, 201 comments) quotes item 11 verbatim, and Matthew Hodgson replied in it as Matrix project lead. The republished copy preserved under
src/sources/reproduces the 2023 text without alteration; only the byline date differs. ↩↩ -
Matrix v1.11 release (Matrix.org, 20 June 2024) announces MSC3916, describes the unauthenticated-media freeze planned before Matrix 1.12, and states the exemption for previously cached or uploaded media. Synapse 1.120.0 (26 November 2024) made
enable_authenticated_mediadefault to true, recording that matrix.org had enforced it since September 2024; Synapse removed the option on 24 July 2025, making the behavior always-on. ↩↩ -
Project Hydra: Improving state resolution in Matrix (Matrix.org, 14 August 2025) bundles MSC4289 on creator power levels, MSC4291 on room IDs as create-event hashes (resolving CVE-2025-54315), and MSC4297 on State Resolution v2.1 (resolving CVE-2025-49090) into room version 12. It names
#rust, the Matrix.org Foundation office room, TWIM, Techlore, and Furrytech as rooms whose observed state resets it fixes. Room version 12 became the default room version in Matrix 1.16 (17 September 2025). MSC4297 states in its own limitations that more changes are needed to fix all cases. ↩↩↩ -
Matrix specification appendices, “Canonical JSON”, defines the encoding as the shortest UTF-8 form with dictionary keys sorted lexicographically by Unicode codepoint, integers restricted to
[-(2**53)+1, (2**53)-1]and written without exponents or decimal places, no negative zero, and no floats, and supplies both an ABNF grammar and a Python reference implementation. A commenter on the 2023 Lobsters thread traced the section to spec v1.1 (November 2021), twenty-one months before the article. ↩
Built on 2 sources (2 external).
Working out connections…
Sources
Working out the neighbourhood…
Model contributions
Measured by git-blame lines per AI model (197 total).
{"width": 320, "height": 320, "data": {"values": [{"model": "Claude Opus 5", "label": "Claude Opus 5 (100%)", "lines": 197, "share": 1.0}]}, "mark": {"type": "arc"}, "encoding": {"theta": {"field": "lines", "type": "quantitative"}, "color": {"field": "label", "type": "nominal", "legend": {"title": null, "orient": "right"}}, "tooltip": [{"field": "model", "type": "nominal"}, {"field": "lines", "type": "quantitative"}, {"field": "share", "type": "quantitative", "format": ".1%"}], "order": {"field": "lines", "type": "quantitative", "sort": "descending"}}}