datahaven-xyz/datahaven · critical · Error
InvalidUpgradeParameters
InvalidUpgradeParameters
Error message
InvalidUpgradeParameters
What it means
The system-v2 pallet's `upgrade` extrinsic throws `Error::InvalidUpgradeParameters` when the supplied `impl_address` or `impl_code_hash` is zero. Upgrading the system contract to a zero address or zero code hash would brick the EVM-side system contract, so these degenerate values are rejected up front (after governance-origin verification).
Solutions
- Deploy the new implementation contract first and use its real address and code hash in the upgrade call.
- Validate `impl_address != H160::zero()` and `impl_code_hash != H256::zero()` in the proposal/submitting script before dispatching.
- Verify argument ordering when constructing the extrinsic call data.
Example fix
// before let addr = H160::zero(); SystemV2::upgrade(origin, addr, H256::zero(), initializer)?; // InvalidUpgradeParameters // after let addr = deployed_impl_address; // from successful forge/Foundry deploy output let code_hash = keccak256(deployed_impl_code); assert!(!addr.is_zero() && !code_hash.is_zero()); SystemV2::upgrade(origin, addr, code_hash, initializer)?;
Defensive patterns
Strategy: validation
Validate before calling
if (implAddress === '0x0000000000000000000000000000000000000000' || implCodeHash === '0x' + '00'.repeat(32)) throw new Error('zero upgrade target'); Type guard
function isNonZeroUpgradeTarget(addr, hash) { return addr != null && !/^0x0+$/.test(addr) && hash != null && !/^0x(00)*$/.test(hash); } Try / catch
try { await api.tx.systemV2.upgrade(implAddress, implCodeHash, initializer).signAndSend(council); } catch (e) { if (String(e).includes('InvalidUpgradeParameters')) abortProposal(); else throw e; } Prevention
- Always deploy the implementation before proposing the upgrade
- Validate all extrinsic args in the proposal tooling
- Check deploy outputs for real address/code hash
- Review upgrade calldata in multisim before signing
When it happens
Trigger: Calling `upgrade(origin, impl_address, impl_code_hash, initializer)` via the governance origin where `impl_address == H160::zero()` or `impl_code_hash == H256::zero()` — typically uninitialized parameters or a failed contract deployment whose outputs defaulted to zero.
Common situations: Proposal/automation scripts passing default H160/H256 values because the new implementation failed to deploy; copying upgrade calldata with placeholder zeros; indexer or multisig tooling mixing up argument order so zeros land in these fields.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- InvalidUpgradeParameters
- InvalidTokenTransferFees
- TransfersDisabled
- InvalidAmount
- InsufficientSovereignBalance
AI-assisted analysis of datahaven-xyz/datahaven@edcb13dbbc (2026-09-13).
Data as JSON: /api/errors/7c350a521a0cd230.
Report an issue: GitHub.
Appendix: source
Thrown at operator/pallets/system-v2/src/lib.rs:146
///
/// Fee required: No
///
/// - `origin`: Must be `Root`.
/// - `impl_address`: The address of the implementation contract.
/// - `impl_code_hash`: The codehash of the implementation contract.
/// - `initializer`: Optionally call an initializer on the implementation contract.
#[pallet::call_index(3)]
#[pallet::weight((<T as pallet::Config>::WeightInfo::upgrade(), DispatchClass::Operational))]
pub fn upgrade(
origin: OriginFor<T>,
impl_address: H160,
impl_code_hash: H256,
initializer: Initializer,
) -> DispatchResult {
let origin_location = T::GovernanceOrigin::ensure_origin(origin)?;
let origin = Self::location_to_message_origin(origin_location)?;
ensure!(
!impl_address.eq(&H160::zero()) && !impl_code_hash.eq(&H256::zero()),
Error::<T>::InvalidUpgradeParameters
);
let initializer_params_hash: H256 = blake2_256(initializer.params.as_ref()).into();
let command = Command::Upgrade {
impl_address,
impl_code_hash,
initializer,
};
Self::send(origin, command, 0)?;
Self::deposit_event(Event::<T>::Upgrade {
impl_address,
impl_code_hash,
initializer_params_hash,
});View on GitHub (pinned to edcb13dbbc)