If you’re running a Polygon PoS node on a Bor or Heimdall binary from before August, your node isn’t on the canonical chain anymore. Not “at risk of” falling off. Already off.
That’s the blunt version of what Polygon Labs put out, and it’s worth sitting with for a second, because the two activation heights in question have already passed. Austin went live on mainnet at block 91,949,700. Kyoto activated at Heimdall height 51,533,000, which Polygon’s own release notice timestamps to Aug. 18 at 10:10:31 UTC. Miss either one, and the fix isn’t a restart. You upgrade, then you catch up, and only then do you follow the network’s accepted history again.
What broke, and what it would have looked like
Polygon’s Aug. 27 security review is careful about one thing: it says there was no observed mainnet disruption from Austin, and it frames the disclosed changes as proactive fixes. Fine. But the failure modes are specific enough to be worth understanding rather than skimming.
Austin dealt with two separate resource-exhaustion problems, and they fail in different directions.
The first involves state-sync events from L1-to-L2 bridge deposits. When Bor processes those, they execute contract code and precompiles, which costs gas like anything else. The gas wasn’t being counted against a fixed block-level ceiling. Enough events in one block, or a single expensive enough event, and block processing slows to the point where the chain stalls transiently. Austin caps that gas.
The second is nastier in a hands-off way. Bor’s TxDependency extra-data field is a hint for parallel execution, supplied by the block producer, and it had no size limit. A producer could stuff an arbitrarily large blob into an otherwise valid sibling block and crash any peer that tried to process it. Austin removed the field from the wire format entirely.
One path delays your blocks. The other kills your peers outright. Polygon classified both as resource-exhaustion risks.
Kyoto’s worst bug was a cheap transaction that cost everyone else
The highest-severity Kyoto fix targets deeply nested google.protobuf.Any messages. The asymmetry is the problem: a sender could cheaply construct a single transaction that forced every validator to spend heavily on decoding it. Cheap for one party, expensive for the entire validator set.
The hardfork adds a byte-level nesting check in two places, at mempool admission and at block-proposal processing, so both paths behave the same way. That consistency matters more than it sounds. A check on one path and not the other is how you end up with transactions that get rejected from the mempool but sail through in a proposed block.
Kyoto also caps fee-coin lists before an O(n) validation scan runs over them. Heimdall’s integration permits one fee coin anyway, so the cap costs nothing in practice.
The rest of Kyoto is edge-case cleanup, and it’s the interesting part
The remaining changes read like a list of things someone found by staring hard at anchoring and milestone logic.
Checkpoint signature recovery bytes get normalized, so a valid signature can’t fail recovery on Ethereum and stall anchoring. Repeated producer-downtime messages become idempotent. Milestone-range votes are bound to the signed parent hash. And a failed future-span creation no longer blocks milestone commitment.
Then there’s the replay-key change, which is the one I’d flag if you care about bridge correctness. Replay keys for topup, clerk and stake events were made injective for out-of-range log indexes, so distinct layer-1 events can’t silently shadow each other. “Silently” is doing the heavy lifting in that sentence.
What you actually have to do
Version floors first. Bor versions earlier than v2.10.0 are incompatible after Austin, and that cutoff applies to every Bor node role, not just producers. The public Bor v2.10.0 release records Austin’s mainnet and Amoy activation blocks. GitHub showed v2.10.1 as the latest Bor release when checked Aug. 28, and v2.10.0 or later gives you Austin compatibility.
On the Heimdall side, validators and full nodes need v0.11.0.
The good news is that both hardforks are plain binary upgrades. No state migration, no genesis change. If your node never diverged, you don’t need to resync at all, which is a meaningfully lower-effort upgrade than Polygon operators have faced before.
If you’re already past the relevant height on an older client, it’s more work. Install the applicable release, roll back to a pre-hardfork point if you need to, and resync under Polygon’s guidance.
One last piece of context on the token: Polygon Ecosystem Token is -2.00% over the past 24 hours. Which tells you roughly what you’d expect. Nobody outside the operator community noticed any of this, and that’s the whole point of shipping fixes before something goes wrong rather than after.