v1.13.0: the record behind the release¶
An article published on 2026-09-16, the Rogue Core-Geth Release Incident Report, tells node operators and mining pools not to run v1.13.0, to move back any node already on it, and to restore the previous node key if they rotated it on this project’s instructions. It claims that nothing in v1.13.0 fixes a vulnerability in v1.12.23. That claim is false, and the article’s advice would leave nodes less secure than the release it warns against. The security fixes in v1.13.0 were reported privately first and made public nearly six months before it shipped.
This page sets out the record: commit metadata, pull requests, release files, advisory records and vulnerability databases. Every answer links to the record it rests on, so it can be checked without trusting this page. Where the article is accurate, this page says so.
The article is published by Classix (classix-dev on GitHub, @classix_dev on X), which credits Istora Mandiri (IstoraMandiri on GitHub) and Diego López León (diega on GitHub) as its authors. Classix is a 2026 Hong Kong company. Its classix.dev domain and its classix-dev GitHub organization were both created on 31 March 2026, and the site’s earliest post is dated 11 May 2026. Its introduction of 9 September 2026, a week before the article, names the same two people as its founders and makes two claims about itself: that of the Cooperative’s closure, “Classix is picking up the torch”, and that Diego López León is “currently the only core maintainer of the Ethereum Classic clients”. Both are the company’s own descriptions of itself, and neither matches what the ETC Cooperative has published. The Cooperative’s own 2024 roadmap names the Ethereum Classic community GitHub repository as where Core-Geth should move, a member of its board has been proposing exactly that on the website since March 2026, and the board has communicated its intent to archive etclabscore/core-geth. v1.13.0 was developed and released from this repository.
For mining pools and node operators
Track releases at ethereumclassic/core-geth and run v1.13.0 or later. The ETC Cooperative board has communicated its intent to archive etclabscore/core-geth, and all future core-geth development is in ethereumclassic/core-geth, alongside the network’s other public goods. Where core-geth is maintained gives the history.
On this page: At a glance · Where core-geth is maintained · What the article recommends · The fixes were disclosed first · Since the release · What has happened since the article · When the work was done · What v1.13.0 fixes that v1.12.23 does not · Review · Test fixtures · Peer discovery · Node key rotation · MESS · Check a release yourself · Do not trust this page. Verify it.
At a glance¶
| The article says | The record shows |
|---|---|
“Nobody proposed it” (the repository ethereumclassic/core-geth) | The ETC Cooperative’s Senior Editor, Donald McIntyre, proposed “Move Core Geth to the Ethereum Classic community repository” in a conference talk, and the Cooperative’s own 2024 retrospective reproduces the slide (page 24 of the PDF, printed page 18). ethereumclassic/core-geth was created on 21 December 2024 from etclabscore/core-geth at its commit of 16 December, 7ef3ecd7a, which the archive-etclabscore-2024-12 branch preserves. |
| “For twenty months it was dormant, until last weekend.” | The security fixes were opened as pull requests #10 to #36 on 20 and 21 March 2026, from commits authored as early as 26 February 2026. Of the 202 commits between the December 2024 archive point and v1.13.0, 75 were authored before September 2026. |
| “Nothing in the rogue release fixes a vulnerability in that version, as is claimed.” | Every v1.12.23 archive carries 55 to 61 Go standard library advisories, each with a CVE identifier, and v1.13.0 carries none. v1.13.0 also clears 44 third-party module advisories that v1.12.23 matches. |
| Argos “was two pull requests … with multiple human reviews.” | GitHub records no review on #699 or #700, the two pull requests that made v1.12.23. |
| “The vectors your build validates consensus against now come from the same place as the code.” | v1.13.0 pins the same fixture commit, 06ec708, that v1.12.23 pins. Git checks the content against that hash, so the fixtures are identical wherever they are fetched from. |
| “A node on Aegis, Hermes or Argos had nothing to rotate for.” | The go-ethereum advisory for CVE-2026-26315 recommends rotating the node key after the upgrade that fixes it. |
| “After that a node on this release finds peers only through infrastructure one person runs.” | Bootnodes and DNS trees start discovery; they do not decide a node’s peers. v1.13.0’s trees list 120 Classic nodes found by crawling the network, published from a public repository, and --bootnodes and --discovery.dns accept any other list. |
| That much change “with no time for anyone else to read it” is “a potential catastrophe” in a client “being pushed at the operators who run the hashrate.” | The article’s own incident record of the pool nodes that ran v1.13.0: “No blocks were lost, no reorg occurred, no funds were affected, and no service went down.” |
| “96 commits … were pushed straight to the main branch of a fork, with no review by anyone.” | Those 96 commits were written between 12 and 14 September. 41 are documentation and 31 are release engineering, much of it fixing what the seven release candidates turned up in the release build. 4 touch dependencies and 3 add tests. The other 17 change the client, including the network defaults, peer discovery and the MESS flags. Each was reviewed against Ethereum client practice before it landed, the test suites ran on every push, and seven release candidates were cut and run before the release. See Review. |
Where core-geth is maintained¶
Core-geth is a public good, and the ethereumclassic organization is where Ethereum Classic keeps its public goods: the ECIPs, the website, the community call archives and ethereumclassic/core-geth.
- ETC Labs developed core-geth until it left the Ethereum Classic ecosystem in 2021.
- The ETC Cooperative maintained it from 2022 through 2024, then entered maintenance mode. Its 2024 retrospective states: “At that time, it will be up to other stakeholders to take on any required maintenance of the ETC client, unless a new plan materializes.” The same report reproduces a conference slide headed “ETC Pathway Proposed by Donald McIntyre”, the Cooperative’s Senior Editor, whose second item reads “Move Core Geth to the Ethereum Classic community repository”. The Cooperative’s published roadmap says the same: Ethereum Classic Pathways, 30 July 2024, lists “Move Core Geth to the Ethereum Classic community GitHub repository: This would restore sovereignty of the community on the node client software.”
ethereumclassic/core-gethwas created in the community organization on 21 December 2024 to carry that maintenance forward, frometclabscore/core-gethat its commit of 16 December,7ef3ecd7a. Thearchive-etclabscore-2024-12branch preserves that point. The repository holds core-geth’s full history up to it, andv1.13.0includes thev1.12.23p2p hardening with its original authorship. In March 2026, ethereumclassic.github.io #1678, opened by a member of the Cooperative’s board, proposed pointing the website’s client entry at it, describing the client as “a community asset”. It carries a draft migration announcement written for the website on 2 August 2026, readable on the site’s own deploy preview. Neither has been merged or published, and the website’s client entry still points at the previous project.- The ETC Cooperative board has communicated its intent to archive
etclabscore/core-geth. Future development continues inethereumclassic/core-geth.
ethereumclassic/core-geth is core-geth’s continuation in the community’s organization, not a rival project. Keeping a reference client in the project’s own organization is common practice, as with Bitcoin Core at bitcoin/bitcoin and go-ethereum at ethereum/go-ethereum.
The ETC Cooperative transition lists the other services moving to the ethereumclassic organization as the Cooperative winds down.
What the article recommends¶
The article tells operators who upgraded to “move it back”, recommends v1.12.23, and says: “Restore your previous node key if you rotated it on the rogue fork’s instructions”.
- Moving back to the published
v1.12.23archives puts the Go standard library advisories back on the node. Eachv1.12.23archive carries 55 to 61, all published before it shipped, and its release build cannot be compiled on a supported Go. Go toolchain lists every one. - Restoring a rotated node key undoes the rotation that the go-ethereum advisory for CVE-2026-26315 recommends (GHSA-m6j8-rg6r-7mv8). A key that served a
v1.12.20or earlier node should be treated as exposed.
The fixes were disclosed first¶
The security work in v1.13.0 was reported privately to the ETC Cooperative, which owns etclabscore/core-geth, in February and March 2026. It was published as pull requests #10 to #36 on 20 and 21 March 2026, and etclabscore/core-geth cut its emergency releases, v1.12.21 and v1.12.22, on 18 and 28 March. v1.13.0 shipped on 14 September, nearly six months after the fixes were public. The March 2026 audit records the sequence.
Since the release¶
No issue reporting a defect in v1.13.0 has been opened in this repository since it shipped, and operators who moved to it have reported stable nodes. The client was run on Ethereum Classic mainnet and Mordor throughout its development, from February 2026 to the release; the March 2026 audit and dependency and toolchain modernization record that validation.
What has happened since the article¶
The toolchain finding is now being acted on in the other repository. The article, published 16 September 2026, states that “Nothing in the rogue release fixes a vulnerability in that version, as is claimed.” On 17 September 2026, pull request #702 was opened at etclabscore/core-geth, titled “build, go.mod: align the Go toolchain with upstream v1.17.5”. It changes 68 files, including go.mod, go.sum, build/checksums.txt, both Dockerfiles and every workflow, and moves the Go version those workflows request from 1.21 to 1.25.
That is the finding this project reported privately in February and March 2026, published in the March 2026 audit, and shipped in v1.13.0 on 14 September: the v1.12.x line is built by toolchains that are out of support. v1.12.21, v1.12.22 and v1.12.23 each left it unchanged, so operators on that line have carried it since the fixes were made public six months ago, and since v1.12.20 shipped in June 2024 before that.
It is the same three changes this project made. The Go toolchain audit names exactly what stops the v1.12.x source building on a supported Go: fjl/memsize, which reaches into runtime internals through //go:linkname that Go 1.23 tightened; blst v0.3.11, which Go 1.24 rejects for a cgo alias receiver; and the go 1.21 directive itself. Pull request #702 does all three. It removes github.com/fjl/memsize and its debug endpoint, moves blst from v0.3.11 to v0.3.16, and changes the directive to go 1.24.0. It also raises the # version:golang pin in build/checksums.txt from 1.22.1 to 1.25.12, and updates golang.org/x/crypto from v0.17.0 to v0.48.0 along with x/sync, x/sys, x/text, x/time and x/tools.
Those dependency updates had been proposed before, and closed. Dependabot opened them against that repository and they were closed without merging: golang.org/x/net v0.18.0 to v0.36.0 (#671, closed 16 April 2025) and to v0.38.0 (#678), golang.org/x/crypto v0.17.0 to v0.35.0 (#677), and github.com/golang-jwt/jwt/v4 v4.5.0 to v4.5.2 (#674), the last three closed on 14 August 2026, the day v1.12.23 was released. Check where those versions ended up: go.mod at tag v1.12.23 still reads golang.org/x/crypto v0.17.0, golang.org/x/net v0.18.0 and github.com/golang-jwt/jwt/v4 v4.5.0.
Other contributors raised the same build problems and those pull requests were closed too: Go 1.24 compiler support (#683, closed 6 February 2026), the blst upgrade for a failing CI job (#691, closed), and dropping the memsize debug endpoint (#701, closed 17 September 2026).
Three things worth checking rather than taking from this page. Whether that work was already under way before the article is not something this page can know; what it can show is the dates above. Go 1.24 left support on 10 February 2026 and Go 1.25 on 19 August 2026, each when two newer major releases existed, under Go’s published support policy, so a release built from either would still carry standard library advisories, fewer than Go 1.21 carries. And pull request #702 was open, not merged, when this page was written; check its state rather than trusting this sentence.
When the work was done¶
Each commit records when it was written as well as when it was last applied. GitHub shows the first on a commit’s page as the date it was authored. v1.13.0’s history was replayed onto this repository in September 2026, so every commit carries a September commit date and keeps its original author date.
The security fixes and the toolchain upgrade were written in February and March 2026:
| Change | Authored | Commit in v1.13.0 |
|---|---|---|
CVE-2025-24883: off-curve points in UnmarshalPubkey | 2026-02-26 | 681c915f0 |
| CVE-2026-22862: ECIES minimum ciphertext length | 2026-02-26 | c46834dd8 |
| CVE-2026-26314 and CVE-2026-26315: public key validation | 2026-02-26 | c19892395 |
| Go toolchain upgrade to Go 1.26 | 2026-03-04 | b7d164018 |
| CVE-2026-22868: disconnect peers sending invalid KZG proofs | 2026-03-20 | 9985c33fb |
They were published as pull requests #10 to #36 on 20 and 21 March 2026, and cross-referenced in etclabscore/core-geth #692 the same weekend. A pull request’s opening date cannot be changed afterwards. The same commits are also in white-b0x/core-geth, where GitHub records them as committed on 25 May 2026, with the same author dates.
The commits dated 12 to 14 September were written on those days. Of the 96 the article counts, 41 are documentation and 31 are release engineering: the release workflows, the build scripts, archive and image publishing, and the release stage. Much of that fixed what the seven release candidates turned up in the release build, such as image attestation, macOS and Windows binary metadata, and publishing the archives from one job. Four commits touch dependencies and three add tests. The remaining 17 change the client: the network defaults, the discovery trees and bootnodes, the MESS flags, chainspec parsing and a medium key derivation tier, which the release report describes, and fixes found running the release candidates, to the Etchash cache and to the Engine API on chains without the merge.
v1.13.0 also carries nine commits authored in etclabscore/core-geth for v1.12.23, the delayed p2p message decoding series, with their authorship unchanged: 68469cb19, 863a59733, b77579985, 92e92dc72, 7a4988919, 14b116bc1, 665b53252, 105dc459d and 62489811f.
What the network is running¶
The article tells operators to move off v1.13.0. Nine nodes were on it. The rest of the network was running a release the audits measure as carrying unpatched advisories, and 158 of those predate the March 2026 emergency patches altogether.
| Running | Nodes | Share | What that version carries |
|---|---|---|---|
v1.12.20 and older | 158 | 30.2% | all six client CVEs, unpatched. Two of them were exploited against Ethereum Classic bootnodes in March 2026 |
v1.12.21 | 50 | 9.5% | the ECIES crash and the key oracle closed. Still missing the UnmarshalPubkey and secp256k1 checks, the RLP work, and the GraphQL depth limit. Built with Go 1.21 |
v1.12.22 | 165 | 31.5% | the remaining CVE backports, but only a partial mitigation of CVE-2026-26313. Introduces the eth_syncing regression. Built with Go 1.21 |
v1.12.23 | 138 | 26.3% | the delayed decoding series, and nothing else in this row is fixed: built with Go 1.21.13, or Go 1.22.1 for Arm, carrying 55 to 61 Go standard library advisories with 43 to 47 whose affected symbols are present in the binary; no GraphQL depth limit; the eth_syncing regression untouched; and a response cap that can disconnect peers answering correctly |
v1.12.24 | 4 | 0.8% | a development build of the previous repository’s master, which is not a release |
v1.13.0 | 9 | 1.7% | Recommended client: six CVEs resolved and the GraphQL limit fixed, built with Go 1.26.8, zero Go standard library advisories |
Source: etcnodes.org, 17 September 2026, 524 Core-Geth nodes of 550 on the network. These figures move: https://api.etcnodes.org/peers is the instrument, and the Go toolchain audit and the March 2026 security audit are where each row’s contents are measured.
What v1.13.0 fixes that v1.12.23 does not¶
The six CVEs in the client’s own code are not where the two lines differ most. etclabscore/core-geth backported fixes for four of them in v1.12.21 and v1.12.22, mitigated CVE-2026-26313 in v1.12.22 and hardened p2p message decoding further in v1.12.23, and declared CVE-2026-22868 not applicable to Ethereum Classic. v1.13.0 patches all six. The March 2026 audit and the August 2026 follow-up record which release carried which. The larger difference lies underneath the client’s code.
- The Go standard library. Every
v1.12.23archive was built with go1.21.13 or go1.22.1, and both Go versions had left support before the release shipped. Each archive carries 55 to 61 standard library advisories, all published beforev1.12.23, 43 to 47 of them with the vulnerable code present in the binary.v1.13.0is built with go1.26.8 and carries none. Go toolchain lists every one. Whether the client can reach each one was not assessed. - Third-party modules. Scanners match 47 advisories against the modules in
v1.12.23, 9 of them with the vulnerable code present: intidwall/gjson,golang-jwt/jwt,gorilla/websocket,consensys/gnark-cryptoandgolang.org/x/text. 44 are absent fromv1.13.0. - Rebuilding
v1.12.23on a newer Go. Its release build does not compile on any supported Go. Built without memsize and without the KZG build tag, it does, and takes the Go standard library fixes. That build still declaresgo 1.21, so Go leaves the limits it added for GO-2025-4012 and GO-2026-4341, two denial-of-service advisories, switched off by default, and it keeps the third-party module advisories above. Go toolchain has the detail. - Snap sync. A response cap in
v1.12.23can disconnect peers that are answering correctly; the August 2026 follow-up measures it.v1.13.0does not carry that cap. - GraphQL.
v1.13.0limits query depth. The article is right that GraphQL is off unless--graphqlis set.
Review¶
GitHub records no second reviewer’s approval on any 2026 core-geth release, in either repository. A GitHub approval is one way to review a change and it is not the only one, so this section describes the review each release did get, on both sides.
How v1.13.0 is reviewed. Changes are reviewed by automated agents against Ethereum client practice before they land, and the security fixes port changes merged upstream in go-ethereum; the March 2026 audit links each upstream change. The test suites run in CI on every push to main, and the audits measure the published binaries rather than the build configuration. The March pull requests carry review comments from their author and from GitHub’s automated Copilot reviewer. The September commits landed on main directly, after that review and the release candidates.
How the 2026 etclabscore/core-geth releases were reviewed. Each release pull request was opened and merged by the same account, with no review recorded on GitHub:
| Release | Pull request | Opened to merged | Reviews recorded |
|---|---|---|---|
v1.12.21 | #694 | about 70 minutes | 0 |
v1.12.22 | #696 | 95 seconds | 0 |
v1.12.23 | #699 | 41 minutes | 0 |
v1.12.23 | #700 | 2 hours 49 minutes | 0 |
Contributions are open. ethereumclassic/core-geth has multiple maintainers with admin access and takes pull requests from anyone. #39, from meowsbits, was opened against the old master branch, answered there, and landed in v1.13.0 as --mediumkdf (cab22a882).
This repository uses AI assistance and says so in its AGENTS.md and CLAUDE.md. The description of #694, the v1.12.21 release pull request, also ends “Generated with Claude Code”. What a release does is settled by reading its code and measuring its binaries, which is what the linked audits do.
Test fixtures¶
Commit 693d8e41b changes where the ETC fixture submodule is fetched from and leaves the pinned commit unchanged. Both v1.12.23 and v1.13.0 pin tests/testdata-etc at 06ec708ea7f3707826142a97a94b61d40c920696. A git checkout is verified against that hash, so a copy fetched from anywhere else either matches it byte for byte or fails to check out.
Peer discovery¶
v1.13.0 starts discovery from three bootnodes and three DNS trees. The trees, all.classic.ethereumclassic.net, all.classic.ethclassic.net and all.classic.ethereumclassic.network, are published from the public ethereumclassic/discv4-dns-lists repository by a crawl of the network, and signed by the key in params/bootnodes_classic.go. The crawl published on 2026-09-14 lists 120 Classic nodes.
Discovery lists start a node’s search; they do not choose its peers. After its first contacts a node finds further peers through the discovery protocol itself. --bootnodes and --discovery.dns accept any other list, including the previous trees, which still resolve. Those trees are published from etclabscore/discv4-dns-lists, in the ETC Cooperative’s etclabscore organization. As communicated by the ETC Cooperative board, the Cooperative is scheduled to dissolve by the end of 2026, and these trees to be archived as it does. v1.13.0 dropped them because this project does not hold their signing key (c0b58570d). Bootnodes and peer discovery explains how the lists are built and how to publish your own.
v1.12.22 also moved its discovery tree. Commit 68bc29bbf changed the Classic tree from all.classic.blockd.info to all.classic.etcdisco.net, and it shipped through #696, merged 95 seconds after it was opened, with no review recorded. Its three Classic bootnodes are the same in every release from v1.12.19 to v1.12.23.
Node key rotation¶
The go-ethereum advisory for CVE-2026-26315, GHSA-m6j8-rg6r-7mv8, states: “We recommend rotating the node key after applying the upgrade, which can be done by removing the file <datadir>/geth/nodekey before starting Geth.” The fix stops new leaks; it cannot recall bits of a key that already leaked. A node key that served a v1.12.20 or earlier node should be treated as exposed, whichever later release closed the flaw, and the v1.12.21 release notes do not mention rotation.
Rename that file rather than deleting it. With the node stopped, move geth/nodekey aside; the client writes a fresh one on the next start. Keeping the old file is what lets you prove later which node an old enode ID belonged to, and a deleted key cannot be recovered. Your enode ID changes either way, so update every peer list, monitoring entry and allowlist that names this node. The migration guide gives the commands and the places to update, including why static-nodes.json is not read and has not been for years.
MESS¶
ECBP-1100, which defines MESS, and ECBP-1110, which recommends shipping it off, are Best Practice documents, not consensus rules. MESS changes which of two competing chains a node prefers during a deep reorganization, and never whether a block is valid. The status of both documents is open in ECIPs #580.
What changed, exactly. This client has activated MESS at block 11,380,000 since October 2020, and the v1.12.x line also carries a deactivation at block 19,250,000, the Spiral block, so a node on that line stops applying it there. v1.13.0 removes the deactivation and keeps the activation, so MESS applies again. params/config_classic.go holds both fields and params/config_etc_test.go asserts the deactivation stays unset.
A node with MESS on and a node with MESS off follow the same chain in normal operation. They can only diverge when a competing chain arrives that would replace blocks the node already accepted, which is what a majority-hashrate attack produces rather than ordinary mining. Before MESS existed, one such attack against Ethereum Classic ran for twelve hours on 31 July 2020 and double spent about $5.6 million; the testing report calculates that holding the same reorganization against MESS would have taken 31 times more hashing power.
Whichever you choose, set your own nodes the same. An exchange’s deposit and withdrawal nodes that disagree about MESS can prefer different chains during a deep reorganization, which is the case that matters. --mess=false puts a node where ECBP-1110 recommends, and changing nothing leaves the protection on. Which setting fits which operator has the trade for each kind of node, including the one case where it cuts both ways: a miner with MESS on keeps mining the chain it had if others accept a deep reorganization, and a miner with MESS off follows whichever chain carries the most total difficulty, including one an attacker paid for. MESS has the full record behind the default, and the confirmation calculator shows what it means for deposit confirmations.
Check a release yourself¶
- Checksums and provenance. Verifying a download checks an archive against its published checksum and its build attestation.
- What built a binary.
go version -m gethprints the Go version and the commit a binary was built from, without running it. - Known advisories.
govulncheck -mode=binary gethlists the advisories that apply to a binary. Go toolchain explains what it reports forv1.13.0.
Do not trust this page. Verify it.¶
Nothing here asks to be taken on faith, this page included. Every document behind it is public, and so is the article. Fill in the version you run, paste this into ChatGPT, Claude, Gemini or any other assistant that fetches URLs, and make your own decision:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
The documents are markdown in the repository under docs/, so a model that prefers raw source can read them there, and git log shows every change any of them has had.