How to retrieve cycles from an abandoned canister

Note that this guide uses dfx version 0.8.1

  1. Create a new identity using
dfx identity new move_cycles
  1. Use the identity created by issuing
dfx identity use move_cycles
  1. Save the principal ID of the move_cycles identity to the environment variable MOVE_CYCLES_IDENTITY by running
MOVE_CYCLES_IDENTITY=$(dfx identity get-principal)
  1. Use the previous identity that is controller of the wallet canister that controls the abandoned canister by issuing the following command and substituting <your_old_identity> accordingly
dfx identity use <your_old_identity>
  1. Make the move_cycles identity the controller of the abandoned canister.
    Make sure you run this command from within a dfx project folder and edit the canister_ids.json file so that the canister id of the abandoned canister is present. If your canister_ids.json file contains those entries,
{
  "assets": {
    "ic": "kwflp-viaaa-aaaae-aaaaa-cai"
  },
  "kanban": {
    "ic": "kren3-yqaaa-aaaae-aaaaa-cai"
  }
}

replace one of the canister ids with the id of the abandoned canister like this

{
  "assets": {
    "ic": "<abandoned_canister_id>"
  },
  "kanban": {
    "ic": "kren3-yqaaa-aaaae-aaaaa-cai"
  }
}

Then run

dfx canister --network ic update-settings --controller $MOVE_CYCLES_IDENTITY <abandoned_canister_id>
  1. Now that the move_cycles identity is the controller of the abandoned canister, switch back to it by issuing
dfx identity use move_cycles
  1. Run the following command to uninstall the canister
dfx canister --network ic --no-wallet uninstall-code <abandoned_canister_id>
  1. Now run the following command to deploy a cycles wallet to the now empty canister
dfx identity --network ic deploy-wallet <abandoned_canister_id>
  1. Finally you can either send cycles to the cycles wallet of your main identity by issuing the following command or accesing the cycles wallet frontend under <abandoned_canister_id>.ic0.app and following the instructions on screen
dfx wallet --network ic send <main_cycles_wallet_id> <amount_of_cycles_to_send>
  1. If you want to you can now stop the wallet canister after you moved the cycles by running
dfx canister --network ic stop <abandoned_canister_id>

and

dfx canister --network ic delete <abandoned_canister_id>
  1. If you no longer need the move_cycles identity you can also remove it by issuing
dfx idenity remove move_cycles
6 Likes

dfx canister --network ic --no-wallet uninstall-code XXXXXXXXXX
the replica returned an HTTP Error: Http Error: status 403 Forbidden, content type “”, content: Requested canister rejected the message, why??

Did you make sure you changed your dfx identity as described in step 6?

Is this still applicable? Seems rather complicate to take back some cycles from a canister.

no, you can now simply run
dfx canister --network ic stop <canister id>
and then
dfx canister --network ic delete <canister id>

1 Like

If you have a canister controlling another canister (and you use cross-canister calls to create, manage, and delete child canisters) can you still just stop and delete a child canister to get the cycles back? I’m assuming perhaps not?

You need to first have a method on the child canister that calls deposit_cycles and deposits the cycles back into the parent canister.

Then you can stop/delete the canister after.

2 Likes

Yeah, I assumed I would need to manually send the cycles back first, but it would be nice if you could “delete_and_reclaim_cycles” in a single command. Not the end of the world though.

Thanks!