# Contract upgrade failed because variables are deleted in openzepplin 5.0

**URL:** <https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341>\
**Category:** Upgrades\
**Tags:** erc721, proxies\
**Created:** [November 2, 2023, 4:29am UTC](https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341 "2023-11-02T04:29:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ben\_Liu](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ben_liu/32/19647_2.png) [@Ben\_Liu](https://forum.openzeppelin.com/u/Ben_Liu)\
**Post date:** [November 2, 2023, 4:29am UTC](https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341/1 "2023-11-02T04:29:12Z")

</div>

I have an ERC721Upgradeable contract deployed to Ethereum main net, using the openzepplin 4.x. Recently I wanted to upgrade our implementation using the Openzepplin 5.0 library. However, after I modify the code, adopted the 5.0 features and ran upgradeProxy in hardhat, i got the following error:

```Initializable: Deleted `_initialized`

> Keep the variable even if unused

Initializable: Deleted `_initializing`

> Keep the variable even if unused

ContextUpgradeable: Deleted `__gap`

> Keep the variable even if unused

ERC165Upgradeable: Deleted `__gap`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `_name`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `_symbol`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `_owners`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `_balances`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `_tokenApprovals`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `_operatorApprovals`

> Keep the variable even if unused

ERC721Upgradeable: Deleted `__gap`

> Keep the variable even if unused

ERC721EnumerableUpgradeable: Deleted `_ownedTokens`

> Keep the variable even if unused

ERC721EnumerableUpgradeable: Deleted `_ownedTokensIndex`

> Keep the variable even if unused

ERC721EnumerableUpgradeable: Deleted `_allTokens`

> Keep the variable even if unused

ERC721EnumerableUpgradeable: Deleted `_allTokensIndex`

> Keep the variable even if unused

ERC721EnumerableUpgradeable: Deleted `__gap`

> Keep the variable even if unused

ERC721BurnableUpgradeable: Deleted `__gap`

> Keep the variable even if unused

AccessControlUpgradeable: Deleted `_roles`

> Keep the variable even if unused

AccessControlUpgradeable: Deleted `__gap`

> Keep the variable even if unused

ReentrancyGuardUpgradeable: Deleted `_status`

> Keep the variable even if unused

ReentrancyGuardUpgradeable: Deleted `__gap`

> Keep the variable even if unused

```auto

These built in variables are either removed in Openzepplin 5.0 or moved to inner structures so I cannot upgrade the implementation contract without messing up storage. How should I resolve this?

#### 💻 Environment
Hardhat on Mac
```

---

<div class="post-metadata">

**Author:** ![ericglau](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ericglau/32/15149_2.png) [@ericglau](https://forum.openzeppelin.com/u/ericglau)\
**Post date:** [November 2, 2023, 1:43pm UTC](https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341/2 "2023-11-02T13:43:47Z")

</div>

It is NOT safe to upgrade existing deployments from 4.x to 5.0 because they use different storage layouts.

The OpenZeppelin Contracts 5.0 readme states:

> **Important**  
> OpenZeppelin Contracts uses semantic versioning to communicate backwards compatibility of its API and storage layout. For upgradeable contracts, the storage layout of different major versions should be assumed incompatible, for example, it is unsafe to upgrade from 4.9.3 to 5.0.0. Learn more at [Backwards Compatibility](https://docs.openzeppelin.com/contracts/backwards-compatibility).

---

<div class="post-metadata">

**Author:** ![Ben\_Liu](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ben_liu/32/19647_2.png) [@Ben\_Liu](https://forum.openzeppelin.com/u/Ben_Liu)\
**Post date:** [November 7, 2023, 4:47am UTC](https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341/3 "2023-11-07T04:47:17Z")

</div>

very helpful, thank you.

---

<div class="post-metadata">

**Author:** ![tomw1808](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/tomw1808/32/21072_2.png) [@tomw1808](https://forum.openzeppelin.com/u/tomw1808)\
**Post date:** [July 8, 2024, 6:57am UTC](https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341/4 "2024-07-08T06:57:13Z")

</div>

Quite old issue, but has anyone tried to just add the gap[xx] to the implementation contracts to keep using the storage slots at the right location and then just use the new proxy contracts with their individual storage slots which are anywhere somewhere (pseudo) randomly located? I am inclined to try, since a lot of functionality is only available in oz 5 contracts (e.g. EIP712 utils), and porting them around is a mess.

---

<div class="post-metadata">

**Author:** ![ericglau](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ericglau/32/15149_2.png) [@ericglau](https://forum.openzeppelin.com/u/ericglau)\
**Post date:** [July 9, 2024, 2:30pm UTC](https://forum.openzeppelin.com/t/contract-upgrade-failed-because-variables-are-deleted-in-openzepplin-5-0/38341/5 "2024-07-09T14:30:43Z")

</div>

@tomw1808 That would not work by default, since OpenZeppelin Contracts v5 would read from the namespaced storage structs rather than the old storage slots. Therefore the old variables would not be used.
