Zebra 6.0.0-rc.0 Release

Zebra 6.0.0-rc.0: NU6.3 “Ironwood” Support and Security Fixes

We are pleased to announce the release of Zebra 6.0.0-rc.0. This release candidate adds Testnet support for the NU6.3 “Ironwood” shielded pool and v6 transaction format, fixes two moderate-severity security issues, ships signed pre-built zebrad binaries for Linux, and includes a state database format upgrade. All node operators are encouraged to test it on Testnet ahead of the final 6.0.0 release.

Security Advisories

GHSA-x6v8-c2xp-928m: getblock Verbosity 2 Side-Chain Panic (Moderate)

The getblock RPC at verbosity 2 panicked for blocks not on the best chain: their transactions’ confirmations are negative and were cast to an unsigned type, crashing the node. The fix changes the confirmations field to a signed type, matching zcashd and the rest of Zebra’s codebase.

Thanks to Taylor Hornby for reporting this issue.

GHSA-m9xx-8rcj-vmgp: Per-Peer Mempool Admission Cap Bypass (Moderate)

Zebra caps concurrent inbound mempool admissions per peer, but the cap only applied to advertised transaction IDs. Directly pushed transactions (tx messages) bypassed it, letting a single inbound peer occupy more than its share of download slots by pushing full transactions instead of advertising them. This release routes directly pushed transactions through the same per-peer admission accounting. It is the direct-push counterpart to the advertisement-path fix shipped in GHSA-4fc2-h7jh-287c.

Thanks to SuplabsYi of Invariant Labs for reporting this issue.

New Features

NU6.3 “Ironwood” Support (Testnet)

Zebra now supports the NU6.3 “Ironwood” shielded pool and the v6 transaction format, activating on Testnet at height 4,134,000. The consensus parameters: v6 version group ID, consensus branch ID, and Testnet activation height, match zcash_protocol. No Mainnet activation height is set yet. The z_gettreestate, z_getsubtreesbyindex, and verbose getblock RPCs expose the Ironwood note commitment tree and its subtree roots from NU6.3 activation. (#10762, #10888)

Coinbase Marker for Zebra-Mined Blocks

Zebra now tags the coinbase input of every block it mines with a :zebra:. As a result, the mining.extra_coinbase_data option is now limited to 86 bytes (previously 94); Zebra refuses to start if the configured value exceeds this. (#10836)

Pre-Built, Signed zebrad Binaries

Pre-built zebrad binaries are now attached to each GitHub release for Linux on x86_64 and aarch64, so operators can run a node without Docker or a source build. Binaries are also installable with cargo binstallzebrad. Each .tar.gz carries a SHA-256 checksum, a Sigstore build-provenance attestation, and a Cosign signature over the checksum manifest. (#10799)

Block Notify Command

A new [notify] block_notify_command option runs a command on each best-chain-tip change, with %s replaced by the new block hash: Zebra’s equivalent of zcashd’s -blocknotify. (#10726)

Resumable Indexer Streaming

When the indexer RPC is enabled, a co-located read-state consumer can now follow the node more efficiently: the non-finalized block subscription resumes from the consumer’s known chain tips instead of re-streaming the whole non-finalized state, and a new GetBlock indexer method lets the consumer fetch blocks it is missing while its finalized state catches up. A new zebra-state read request, ReadRequest::FindForkPoint, returns the most recent block in a caller-supplied locator that is on the best chain, the fork point, for clients tracking chain reorganizations through a read-only state service. (#10776)

Regtest Coinbase Spend Restrictions

A new Regtest configuration option, should_allow_unshielded_coinbase_spends, forbids spending coinbase outputs into transparent outputs: the inverse of zcashd’s -regtestshieldcoinbase. It defaults to allowing such spends, preserving existing Regtest behavior. (#10698)

Bug Fixes

Sync Stall Near the Chain Tip

A timeout waiting for a transparent input UTXO during transaction verification is now treated as a missing input rather than an internal error, preventing a sync stall near the chain tip. (#10810)

getblocktemplate Coinbase Caching

getblocktemplate now caches the built coinbase transaction per block, so repeated short-poll requests within the same block no longer rebuild it. This prevents CPU saturation and multi-second template latency when mining to a shielded address. (#10847)

Indexer Syncer Subscription Churn

The co-located read-state syncer (used by indexers like Zaino) no longer drops and re-creates its non-finalized block subscription every second while its view of the finalized state lags the node’s. (#10818)

invalidateblock / reconsiderblock Edge Cases

Fixed edge cases in invalidateblock and reconsiderblock (chain-root and same-height sibling-tip invalidation, and repeated reconsideration) that could cause a panic. (#10586)

Changed

State Database Format Upgrade to 28.0.0

The state database format is bumped to 28.0.0 for the NU6.3 “Ironwood” shielded pool. This is a major-version bump that is restorable in place from the previous major format (no resync required): an in-place migration backfills the genesis Ironwood note commitment tree and anchor, creates four new (initially empty) ironwood_* column families, and widens the chain value pool record to include the Ironwood pool. The getblockchaininfo and getblock valuePools now include the ironwood pool, which will be at zero until NU6.3 activates.

Other Changes

  • Upgraded the librustzcash crate cohort to the NU6.3 pre-release wave for V6 transactions and Ironwood support. (#10762)

  • Bumped anyhow to 1.0.103, clearing RUSTSEC-2026-0190. (#10849)

  • Opening a Zebra state read-only now fails with a clear error instead of panicking when the cache directory is missing or unreadable, when no database exists at the configured path, or when an ephemeral database is also configured. The read-write open path is unchanged.

Other Security Improvements

  • Zebra’s release Docker images are now reproducible: an independent rebuild of a published zebrad from the same commit produces the same binary. The Rust toolchain and the Rust and Debian base images are pinned by exact version and digest, and build paths and file timestamps are normalized. Release images are also built without the shared build cache, so a published image cannot inherit a layer from a lower-trust build. (#10798)

  • Release Docker images are signed and carry build provenance and a signed SBOM, so anyone can confirm an image came from Zebra’s CI with cosign verify or gh attestation verify. (#10798)

  • Zebra now uses a constant-time comparison for RPC cookie authentication. (#10567)

  • Released zebrad binaries report their source commit in zebrad version. (#10798)

Upgrading

This is a release candidate intended for Testnet testing ahead of the final 6.0.0 release. The state database format upgrade to 28.0.0 migrates in place, so no resync is required. You can find the release on GitHub, crates.io, and Docker Hub.

Thank You to Our Contributors

This release was made possible by the work of @andres-pcg, @arya, @conradoplg, @dannywillems, @emersonian, @gustavovalverde, @nuttycom, @oxarbitrage, @syszery, @upbqdn, and @zmanian. Thank you for your continued contributions to Zebra.


Zebra is the Zcash Foundation’s independent, Rust-based implementation of the Zcash protocol. Learn more at github.com/ZcashFoundation/zebra.

12 Likes

Up and running! :saluting_face:

1 Like

Thank you :grinning_face:

No Mainnet activation height for Ironwood yet, is that waiting on the audit work or just on the final 6.0.0 shipping first?

Hmm so cipherscan is running zebra 6.0.0-rc.0 on testnet and it’s hitting repeated “CommitSemanticallyVerifiedError(Duplicate)” in the sync pipeline. Node syncs a batch then stalls for ~67s before retrying. Needs a restart to catch up. Anyone else seeing this?

EDIT: Restarting the node seems to unblock it but happened twice already.

1 Like