[deprecated] Private Key Reuse Detected! How to unblock your funds.
In certain cases, the official iota GUI wallet will display the warning above and effectively block you from transferring your funds. This article will help you to get access to your iotas again.
Edit: This article focuses on the deprecated Iota GUI wallet. For tips on how to solve the same problem in the Trinity wallet switch to this article:
Warning: Funds on spent addresses! How to unblock your funds
This is the second part of a two-part story. The first part of this story focuses on what the error means and how you actually got into this situation.
There are two main reasons for the key reuse warning to appear. Pending transactions and funds on used addresses. Pending transactions will be checked first because if this is your issue it can be easily solved without adding any further risk to your funds.
However, if no pending transactions can be found it means you have funds on an already used address and we will use the official iota command-line wallet (cli wallet) to move your funds. Be aware that there is a certain risk involved, which will be explained in detail later on.
1. Pending transactions
A pending transaction can block you from sending iotas in the wallet. Although transactions get confirmed quickly in most cases it can happen that they stay pending for a while. The way the iota tangle works, another transaction has to pick yours as a tip to confirm it. Due to the nature of the tip selection algorithm the older a transaction is, the less likely it will be picked to be confirmed by other transactions. If a transaction is days or even weeks old, it will probably not be picked at all anymore and it can stay pending forever.
That is why you sometimes have to actively push your transaction to be confirmed.
1.1 Find pending transactions
First, you need to find any pending transaction with a value. Zero value transactions do not need to be confirmed and cannot block your wallet.
Open the history section of the wallet and look at the list of transfers. The ones at the top of the list are the most recent transactions.
Find the ones that say Pending. Unfortunately, the history can also seem a bit confusing as you might encounter multiple entries like this:
You see three transactions, one confirmed and two pending. In fact, these three entries in the history are reattachments or copies of the same bundle. If you click Show bundle on one of the pending ones you get more detailed information.
In the Bundle Details dialog, you can see a more accurate representation of the status telling you that a reattachment of this transaction was confirmed already. Thus, this transaction does not count as unconfirmed regarding the blocking of your funds and you can ignore it.
Go through your full history and check for other pending transactions.
1.2 How to confirm a pending transaction
If you have identified one or more pending transactions click on Show bundle.
The first button Rebroadcast is rarely ever used and only useful in the edge case where the node you sent the transaction to did not properly broadcast it to its neighbors. Use the Reattach button instead to create a fresh copy of the complete bundle at a different location on the tangle. This is safe and does not publish any additional part of the private key. The new transaction now has a much higher chance of getting picked to be confirmed by other transactions.
After successful reattachment, the Reattach button will change its caption to Promote.
You can further increase the chance of confirmation by promoting your transaction. This will make it even more popular for being selected as a tip by other transactions.
Each time you hit the Promote button the wallet will promote your transaction 5 times.
As a rule of thumb, you can reattach a transaction if it is older than 30 minutes and promote as many times as you like in between.
If you confirmed the last pending transaction in your wallet you should be free to send further transactions without seeing the key reuse warning. If you did not find pending transactions or still see the warning you will have to move your funds using the cli wallet.
2. Move funds
Although it might seem this way at this point, your current seed is not broken. If you want to you can still use it later on. However, to make things easier and to have a fresh start we will transfer all your funds to a new seed.
First, make sure you have a new seed available. DO NOT use any online seed generator. If you are in any way unsure how to generate a seed, read Koen’s article: The Secret to Security — Is Secrecy.
Use the new seed to log into the wallet and generate a new receive address. Copy that address somewhere so you have it at hand. This will be your target address from now on. Also, be sure to have a safe backup copy of your new seed.
2.1 Move unblocked funds first
The way the GUI wallet and also Trinity work you will find that not all your funds are blocked. Only the amount on the affected address(es) actually needs to be transferred using the cli wallet. The remaining funds can be moved using the official GUI wallet or Trinity. These funds are never at risk to be stolen, but in the case something goes wrong during the cli wallet transfer it possible to end up in a situation where these previously unaffected funds can become blocked, too. This is only an edge case with a very low probability but still recommended, especially if you have substantial amounts of funds on your seed. If you want to skip this step you can directly jump over to Use the cli wallet to move blocked funds.
In order to transfer the unaffected balance first, you need to know how much it actually is. If you already identified the address that is blocking your funds you can just subtract the funds on it from your total balance and issue a new transaction to the new target address with the resulting amount.
If you do not know which address is blocking you and how much balance is affected you need to do some detective work. Using the Trinity wallet this is a fairly simple task as there is a nice overview showing your addresses and their balances. You can find this list by clicking on Settings→ Account Management → View addresses (Use the Account menu when on Trinity desktop). Scroll through your list and find a used address with funds on it. Used addresses are highlighted in red with crossed-out characters.
In the screenshot above you can see the address 9GIYJ… is used but still has 100i on it. These funds are blocked, but assuming that this the only affected address, the remaining 115i (total amount of 215i minus blocked 100i) can be moved without issues.
The GUI wallet lacks such a nice list of addresses and their balances. In case you can only use this wallet, identifying the affected address is a bit more complicated. You can clear unblocked funds one address at a time using the following procedure. It might be time-consuming as you have to perform two transactions for every address you have to clear, but if you have considerable amounts of funds this is still recommended.
Use the wallet to send 1i (not 1Ki or Mi) to your target address. If the wallet accepts the transfer without showing the key reuse warning again you have at least one address with unblocked funds.
Then find the 1i outgoing transaction in your history and click on Show Bundle.
This will show all transactions in the bundle. First, there is the 1i transaction, then you see a -1000i transaction meaning that an address was used for sending that had previously 1000i on it. Finally, you see a transaction that sends the remainder of 999i to another address of your seed. Now you know that another 999i is available for sending. Make sure the 1i transaction is confirmed, then issue a second one with the amount of the remainder. The amount may, of course, be different in your case.
Repeat this until even sending a 1i transaction will show the key reuse warning.
2.2 Use the cli wallet to move blocked funds
At this point only blocked funds should remain in your wallet. The Iota command line wallet (cli wallet) is a simple wallet software without a graphical user interface published by the Iota Foundation. It is completely controlled via the command line. We will use it here because in contrast to most other wallets (GUI wallet, Trinity) it does not prevent you from reusing the private key of an address.
It is important to understand that the key reuse warning in the other wallets is there for a reason. When using an address for sending multiple times it poses a certain risk that these funds will get stolen. Each outgoing transaction from an address publishes a random 50% of the private key of this specific address. The risk of theft increases with every additional outgoing transaction. If the address was only used once previously the risk is fairly low. But if it was used 3 times or even more than it becomes easy for malicious parties to access your funds. It has to be said that only the funds on this specific address are at risk and no other address nor any part of your seed is ever at published or in danger. Please keep all this in mind as I cannot be made accountable for any losses that may occur. If you feel unsure or uncomfortable in any way following this procedure, join the iota Discord and explain the details of your case in the #help channel to look for another solution.
2.3 Installing cli wallet
Navigate to the official Node.js web site (https://nodejs.org/) and download the installer appropriate to your operating system. It is recommended to choose the long term support version (LTS). Download and run the installer. Once it is finished it is time to open the command line interface of your operating system. For Windows go to the start menu, type cmd and hit Enter. On Mac OS X use the Spotlight search to look for terminal and start it.
Once at the command line interface we can make use of npm, the packet installer that is part of Node.js to directly download and install the iota cli wallet by entering this line:
npm install -g iota-cli-app
Hit Enter and wait until the installation is finished.
2.4 Sending blocked funds
You will need to have a target address from a fresh seed and the cli wallet installed to proceed. Start the cli wallet with this command:
After starting it will look like this:
By default, the wallet will try to connect to a node running locally on your computer. If you do not run a local node you can enter a trusted public node. Here we will use one of the nodes run by an Iota Foundation member (Ralf Rottmann): nodes.iota.fm:80.
You can choose the same node or pick a different one that you trust. A list of nodes is for example available here https://iota.dance/
Connect the wallet to the node by typing
After a few seconds, the wallet will be connected, visible by the green checkmark after the node name.
Now enter your seed:
Replace YOURSEED with your own seed and press Enter. If you paste your seed from the clipboard you can use right-mouse-click and Paste on Windows and Shift-Command-V on OS X.
Choose No when asked to save the seed locally for auto-completion (type N and hit Enter).
After entering your seed the wallet will automatically retrieve the full account data in the background. Depending on the number of addresses you have already used it can take the wallet up to a couple of minutes to check all addresses. Once finished it will notify you and also display the available balance (1.2Mi or 1200Ki in this case).
If the balance is not displayed you can specifically request receiving it with the balance command.
It is recommended to move unblocked funds out first with the wallet of your choice, so at this point, you should see the balance that matches the funds on the blocked address(es).
When sending funds with the cli wallet you need to give the amount as a number of iotas, not Ki, Mi, or Gi. This means if you see a unit like K, M or G behind the balance you need to convert it into the amount in iota. The 1.2 Mi are shown as 1200 Ki, which again equals 1200000 iotas. Use this chart for reference if you are unsure about the units.
Now you have everything to issue the final transfer command. Remember that from the moment the transaction is published your funds are at risk until the transaction is confirmed. Even if this is only a small risk, you want to have the new transaction confirmed as fast as possible.
To finally send the funds from the blocked address(es) enter the command like this and double-check it before hitting Enter:
transfer ADDRESS amount
Replace ADDRESS with the target address you want to send your funds to and replace amount by the number of iotas you want to transfer. Do not include any unit when defining the amount. With my wallet the command could look like this:
transfer HBMYPAZXKHMGUVHZGEATCWCVUXLMSGZQFVLGJNYJMBWEFAUAHMHDXWKBANJDSDZHPVOOVFZVWSHAKFJODRJWNMPPXW 1200000
The wallet checks the validity of the address, so if you include a typo somewhere it will be detected due to the invalid checksum. You would see this error message in that case:
If you see this message
it means that you probably entered a unit (i, Ki, etc) after the amount. Make sure to only give the number of iotas to transfer.
After hitting Enter on the correct transfer command the wallet will start creating the transfer bundle and sending it to the tangle. This can take up to a few minutes. When finished it will look like this:
Now is the time to promote the new transaction to help to get it confirmed faster. It might take a minute until the transaction will show up in the history of the wallet, but then you can use your wallet to promote it.
As soon as the transaction is confirmed your funds have safely arrived on the new seed.
Questions or comments? Find me on the Iota Discord (HBMY289). Special thanks go to Discord users olaz preton and berdiin who helped with proof-reading this article.