Skip to main content
Why this emergency upgrade happenedBitGet, an exchange unrelated to Injective, reported a compromise and requested assistance recovering its funds, some of which may have interacted with Injective alongside other major chains. This patch introduced an on-chain blocklist to prevent an attacker from moving BitGet’s affected funds. It was a one-time emergency intervention to assist BitGet’s fund recovery and support the wider ecosystem. Initial distribution and coordination focused on validators, with public communication limited to avoid alerting the attacker before containment was in place.We recognize that exchanges and other node operators did not receive sufficient advance notice or clear instructions that they also needed to upgrade. We apologize for the resulting disruption. This exceptional response does not replace the normal coordinated upgrade process.On October 7, a transaction involving a blocked address exposed the difference between patched and unpatched nodes. Unpatched nodes encountered an AppHash mismatch while the network continued producing blocks. All mainnet nodes must run the patch, including sentries, RPC nodes, and exchange infrastructure.

Summary

v1.20.4-bl.2 is an emergency patch on the v1.20.4 release line for Injective mainnet (injective-1). Its consensus blocklist activated at block 184,950,000, which has already passed. Upgrade now; there is no scheduled chain halt, governance upgrade handler, or state migration for this patch. Do not wait for a halt or set a new --halt-height. This applies to validators, sentries, full nodes, public and private RPC/broadcast nodes, and nodes serving exchanges, explorers, and other integrations.

1. Choose and verify your release

Choose either the binary archive or Docker image. Docker operators can skip the archive downloads and use the image directly.

Option A: binary archive

The official release manifest lists the hosted binaries. Download the archive for your platform: For Linux AMD64, download into a staging directory without replacing your running binary:
Continue only if the checksum reports OK. Then extract the archive:
For macOS, use shasum -a 256 and compare the archive against the corresponding entry in the checksum file.

Option B: Docker image

The initial release distributed the patch as the following Docker image:
Pull the image and verify its binary without mounting your node data:
The initial release recorded the following output for AMD64:
Continue through the stop, backup, recovery, and restart steps below using your existing container deployment. Keep the old image available: affected nodes must complete rollback with that image before switching to the patch. The Docker image includes the runtime libraries, so container operators do not need to install the archive’s libwasmvm on the host.

2. Stop the node and back up its state

Stop the node through your existing service manager or container deployment. Stop its supervisor as well so it cannot automatically restart during recovery. Confirm that no injectived process is accessing the node’s data directory. Back up your node configuration, keys, and data before proceeding. Keep the existing binary available until any required rollback is complete. The commands below assume the default home directory, ~/.injectived; use your configured --home path if different. Docker Compose example: Run the commands from your existing Compose project, using the same Compose files and environment as your normal deployment. Set node_service to your actual service name and container_node_home to its existing home path inside the container; the values below are examples. Confirm that this home is backed by your existing bind mount or named volume, then stop the service:
Back up that mounted node home after shutdown. Keep these variables set for the Compose commands below. If you use plain Docker or another orchestrator, stop the existing node container through that deployment and preserve its mounts and settings.
Validators: After the node has fully stopped, separately back up ~/.injectived/data/priv_validator_state.json outside the data directory. Preserve this exact signing state through rollback or snapshot recovery and restore it before restarting. For a remote signer, preserve its signing state using your existing signer procedure. Never reset signing state or run two instances with the same validator key.

3. Recover an affected node, if needed

Only perform this step if your node encountered the October 7 AppHash mismatch. A reported error was:
For archival nodes or nodes with large databases, contact support to confirm a recovery approach before attempting rollback; restoring a suitable snapshot may be preferable. With the node stopped, use the same binary version that was running when the mismatch occurred, before installing the patch:
This one-block rollback followed by the binary upgrade was tested during the incident. Use the actual executable from your service configuration, not a different injectived on your shell’s PATH.
  • Cosmovisor: Run rollback using the existing $DAEMON_HOME/cosmovisor/current/bin/injectived, with --home pointing to that node’s home directory.
  • Containers: Run the rollback as a one-off command using the old image, the same data volume, node home, and user permissions. Keep the normal node container stopped throughout.
For Docker Compose, leave the service’s image set to the exact old image used by the affected node until rollback succeeds. Run this instead of the host rollback command above, after completing the backup:
This reuses the service’s configured mounts, environment, and user. The example assumes injectived is available directly in the image; preserve any required initialization if your deployment uses a custom wrapper. Wait for rollback to finish successfully before replacing the binary. The incident recovery instructions estimate roughly 10 seconds to one minute; large or archival databases can take substantially longer. Do not repeatedly roll back additional blocks if the command fails or the mismatch persists. Keep the node stopped and contact support with its version, height, and logs. If rollback is unavailable or fails, obtain a suitable snapshot through the Chain Portal or your Injective support contact. A snapshot from before block 186,223,485 can be replayed with the patched binary. Preserve your validator signing state and follow the snapshot recovery procedure.

4. Install the patch

Once any required rollback has completed:
  • Binary deployments: Replace the injectived executable used by your service with the one from the verified archive. Install the bundled libwasmvm library in the library location used by your deployment, and preserve the service’s ownership and permissions.
  • Cosmovisor: Replace injectived in $DAEMON_HOME/cosmovisor/current/bin and place the bundled library where your service loads it. There is no upgrade handler for this patch, so placing it in a new upgrades directory will not activate it automatically.
  • Containers: Update the existing deployment to injectivelabs/injective-core:v1.20.4-bl.2, retaining its data volume, configuration, user, and startup flags.
For Docker Compose, change only the node service’s image value (or the environment variable supplying it) to injectivelabs/injective-core:v1.20.4-bl.2. Pull and verify the configured image while the node remains stopped:
Before starting, run version against the exact executable or image your service will use and confirm:

Optional: local mempool blocklist

The consensus blocklist is built into the patched binary and requires no configuration. The following app.toml entry adds local transaction-admission filtering and is optional; it is not a substitute for upgrading the binary. If you enable it, add this entry at the top level of ~/.injectived/config/app.toml, before any TOML section headers such as [api]:
If the key already exists, update it without duplicating the key or removing any other configured addresses. Invalid addresses prevent the node from starting.

5. Restart and verify

Validators must restore and verify the signing-state backup taken after stopping the node before restarting. Start the node through your existing service manager or container deployment. For Docker Compose, recreate the service with the new image, then verify the binary inside the running container and inspect its logs:
Use up to apply the image change; restarting the old container alone does not replace its image. For plain Docker or another orchestrator, recreate the stopped node container from the patched image using its existing mounts, ports, environment, user, and startup arguments. Keep only one instance using the node’s data and validator key. Check your logs for successful startup and confirm that the AppHash mismatch no longer appears. Query your node’s local RPC endpoint (adjust the address if needed):
Confirm that:
  • The network is injective-1.
  • The block height advances across successive checks and catches up to the network.
  • catching_up becomes false once synchronization completes.
  • Validators resume signing, and exchange/RPC operators verify their downstream services receive current blocks.
Repeat the upgrade for every node you operate, including sentries and RPC nodes that do not participate in validation.

Support

If recovery fails, keep the node stopped and share the binary version, last processed height, database backend, and relevant error logs with your existing Injective coordination contact or the team on Discord. Do not share private keys or signer credentials.
Last modified on October 7, 2026