Key takeaways
- The spl-token CLI closes an empty Solana token account with spl-token close --address <ACCOUNT>, returning its 0.00148844 or 0.00203928 SOL rent deposit for a 5,000-lamport network fee.
- spl-token gc --close-empty-associated-accounts closes every empty associated token account owned by the CLI keypair, one transaction per account, for the classic SPL Token program unless --program-2022 is added.
- spl-token close refuses to close a token account that still holds tokens; spl-token burn <ACCOUNT> ALL empties it first, and burning is permanent.
- The spl-token CLI charges no service fee: closing 100 token accounts costs about 0.0005 SOL in base fees and returns 0.149 to 0.204 SOL of rent.
- The main limit of the spl-token CLI is signing: it needs a keypair file or a hardware wallet in the terminal, and it sends one transaction per account.
The short answer
To close a Solana token account from the command line, install the SPL Token CLI, list your accounts with spl-token accounts --verbose, and run spl-token close --address <ACCOUNT> on each empty one. To close every empty account in one command, run spl-token gc --close-empty-associated-accounts. Each close returns 0.00148844 or 0.00203928 SOL of rent and costs only the 5,000-lamport network fee. There is no service fee.
What do you need before using the spl-token CLI?
You need the spl-token binary, a configured RPC endpoint, and a signer the CLI can use for the wallet that owns the accounts. Concretely:
- Install the CLI. At the time of writing, in October 2026, the official SPL Token CLI reference installs it with
cargo install spl-token-cli(the page pins a specific version) and notes thatspl-tokenalso ships with Agave CLI releases. If you install the Solana CLI by following the Solana installation guide, check withspl-token --versionwhether you already have it. - Point it at mainnet.
spl-tokenreads the Solana CLI configuration, sosolana config set --url mainnet-betais enough. Any command also accepts-uwith a URL if you use your own RPC. - Give it a signer.
solana config set --keypair <PATH>sets the default keypair. It can be a keypair file or a hardware wallet URL such asusb://ledger.
The third step is where most people stop. If your wallet lives in a browser extension, the CLI cannot ask it to sign, and the only way to use the CLI is to put that wallet's key somewhere the terminal can read. I would not import a main wallet's seed phrase into a terminal just to save a few cents of rent; that is the trade-off the rest of this post assumes you have thought about.
How do you list your token accounts with the CLI?
Run spl-token accounts --verbose, which prints every token account the configured keypair owns, empty ones included, with the program, the mint, the account address, any delegate or close authority, and the balance. Without --verbose you get only the mint and balance, and you need the account address to close a specific account.
Useful variations, all checked against the CLI source at the time of writing:
spl-token accountswith no program flag queries both the SPL Token and Token-2022 programs.spl-token accounts --owner <ADDRESS>lists another address's accounts, read-only.spl-token accounts --externally-closeableshows only accounts whose close authority is someone else, which you will not be able to close.spl-token accounts --addresses-onlyprints just the account addresses, handy for scripting.
Rows with a balance of 0 are your candidates. An account marked "Aux" is an auxiliary token account: one that is not at your wallet's associated address for that mint. The CLI prints a reminder to run spl-token gc when it finds one.
How do you close one token account with spl-token close?
Run spl-token close --address <TOKEN_ACCOUNT_ADDRESS>. The CLI checks that the balance is zero, sends a CloseAccount instruction signed by the owner, and the full lamport balance of the account goes to the owner. The options that matter:
| Option | What it does |
|---|---|
spl-token close <TOKEN_MINT_ADDRESS> | Closes your associated token account for that mint, without looking up its address |
--address <TOKEN_ACCOUNT_ADDRESS> | Closes a specific token account, associated or auxiliary |
--recipient <ADDRESS> | Sends the SOL to another address; the default is the owner |
--close-authority <KEYPAIR> | Signs as the account's close authority when it is not the owner |
--fee-payer <KEYPAIR> | Pays the network fee from another keypair, useful if the wallet has no SOL |
--with-compute-unit-price <MICRO_LAMPORTS> | Adds a priority fee when the network is busy; see how much priority fee to pay |
--program-2022 or --program-id <ADDRESS> | Forces the token program; normally not needed for close |
You rarely need a program flag for close. When you pass a mint or an account address, the CLI reads which program owns it and uses that, so Token-2022 accounts close with the same command. Reading the CLI source, it also handles one Token-2022 case for you: if the account holds withheld transfer fees, it sends a harvest transaction first, then the close. The other Token-2022 conditions, frozen and confidential accounts, are covered in how to close Token-2022 accounts.
Wrapped SOL is the exception to the empty rule. A wSOL account can be closed with a balance, and closing it returns the wrapped SOL together with the rent; spl-token unwrap does the same thing.
How do you close an account that still holds tokens?
Empty it first, then close it. spl-token close refuses to send a close for a non-native account with a balance and tells you how many tokens are left, so the order is:
- Decide whether the balance is worth anything. If it has a market, selling beats burning. Selling from the CLI is not practical, but Sell Dust for SOL swaps small balances through Jupiter and closes the account in the same transaction, for 5% of the SOL received plus 5% of the rent.
- Burn what is left.
spl-token burn <TOKEN_ACCOUNT_ADDRESS> ALLdestroys the whole balance; theALLkeyword saves you from typing the exact amount. Burning is permanent. - Close.
spl-token close --address <TOKEN_ACCOUNT_ADDRESS>.
That is two transactions per account and two network fees. A burn fails if the account is frozen, and a frozen account with a balance cannot be emptied at all until the token's freeze authority thaws it. The other errors you can hit, with their codes, are listed in why you can't close a Solana token account. If you would rather do burns in a browser, the Burn Tokens tool charges 0.005 SOL per burn and can close the emptied account in the same transaction.
What does spl-token gc do?
spl-token gc is the CLI's garbage collector: it cleans up every token account of one program for the configured owner in a single command. Reading its source at the time of writing, for each token it:
- closes empty auxiliary accounts;
- moves the balance of non-empty auxiliary accounts into your associated account and closes them, creating the associated account first if it does not exist, which costs a new rent deposit;
- closes empty associated accounts only when you add
--close-empty-associated-accounts; - never closes an associated account while any account for that token holds a balance;
- skips frozen accounts, and skips accounts with a separate close authority with a note telling you why.
So the bulk command is spl-token gc --close-empty-associated-accounts. Without the flag, gc leaves your empty associated accounts open, and those are the bulk of what most wallets have. gc never burns anything, so accounts with dust stay open.
Two limits are easy to miss. gc scans one token program per run, and by default that is the classic SPL Token program, so run spl-token gc --program-2022 --close-empty-associated-accounts as a second pass for Token-2022. And gc closes empty accounts directly, without the withheld-fee harvest that close does, so a Token-2022 account with withheld fees fails inside gc and needs spl-token close --address.
How much does closing token accounts with the CLI cost?
Only network fees. The CLI sends one transaction per account for both close and gc, each with one signature, so each close costs the 5,000-lamport base fee plus any priority fee you add. The rent returned dwarfs it:
| Empty accounts | Base fees | Rent returned (new accounts) | Rent returned (older accounts) |
|---|---|---|---|
| 10 | 0.00005 SOL | 0.0149 SOL | 0.0204 SOL |
| 50 | 0.00025 SOL | 0.0744 SOL | 0.1020 SOL |
| 100 | 0.0005 SOL | 0.1488 SOL | 0.2039 SOL |
| 500 | 0.0025 SOL | 0.7442 SOL | 1.0196 SOL |
Accounts with a balance add a burn transaction each, and a gc that moves balances may add one to create an associated account. Those are small amounts too. The background on why older accounts return more is in what Solana rent is.
When is a batch tool easier than the CLI?
A batch tool is easier when your wallet lives in a browser or on a phone, when you have dozens of accounts, or when some of them hold dust. The CLI is free and I would not talk anyone who already uses it out of it. The differences are practical:
| spl-token CLI | SOLTidy Token Account Closer | |
|---|---|---|
| Service fee | None | 5% of the SOL recovered, in the same transaction |
| Signer | Keypair file, hardware wallet, or typed seed | Any Solana browser or mobile wallet |
| Accounts per transaction | 1 | Up to 12 |
| Token programs per run | One for gc; close detects it | Both, in one scan |
| Dust balances | Burn manually first | Can burn and close in the same transaction, after a warning |
| Older accounts you keep | spl-token withdraw-excess-lamports, one at a time | Withdraws the excess automatically |
| pump.fun volume accumulators | Not covered | Closed in the same batch |
The Token Account Closer shows every closable account and the SOL it holds before you sign, simulates every batch, and charges nothing if a transaction recovers nothing. For 100 accounts that is about 9 signatures instead of 100 commands. If you want token accounts, stake, NFTs, dust and pump.fun rewards handled in one scan, the Solana wallet cleanup on the home page does that, with each part priced at its own tool's fee.
I built the closer because I kept a trading wallet in a browser extension and did not want its key in a terminal. If your key is already in a terminal, use the CLI. For a side-by-side of wallets, the CLI and other services, see the ways to reclaim Solana rent compared.
Bottom line
The spl-token CLI closes Solana token accounts for network fees alone: spl-token accounts --verbose to find them, spl-token burn <ACCOUNT> ALL for leftovers, spl-token close --address <ACCOUNT> for one account, and spl-token gc --close-empty-associated-accounts, plus a --program-2022 pass, for all of them. Its costs are signing and one transaction per account, not money. If your keys live in a browser wallet, the Token Account Closer does the same closes in batches for 5% of what it recovers.
Questions & answers
What is the command to close a Solana token account?
spl-token close --address <TOKEN_ACCOUNT_ADDRESS> closes a specific token account and sends its rent to the owner. spl-token close <TOKEN_MINT_ADDRESS> closes your associated token account for that mint instead. Add --recipient <ADDRESS> to send the SOL somewhere other than the owner. The account must hold zero tokens, except wrapped SOL.
Can the spl-token CLI close all empty token accounts at once?
Yes, with spl-token gc --close-empty-associated-accounts. gc closes empty auxiliary accounts by default, moves balances out of auxiliary accounts into the associated account, and with the flag also closes every empty associated account. It sends one transaction per account and checks one token program per run, so run it again with --program-2022 for Token-2022.
Does closing token accounts with the CLI cost anything?
Only Solana network fees. Each close is its own transaction with one signature, so it costs the 5,000-lamport base fee, 0.000005 SOL, plus any priority fee you set with --with-compute-unit-price. The rent deposit returned is about 300 to 400 times that fee, so every close is net positive.
How do I close a Token-2022 account with spl-token?
spl-token close --address <ACCOUNT> works for Token-2022 accounts without extra flags, because the CLI reads the owning program from the address you pass. If the account holds withheld transfer fees, the CLI sends a harvest transaction first. For spl-token gc you need --program-2022, because gc otherwise only scans the classic SPL Token program.
Why does spl-token close say the account still has tokens?
Because it does. The CLI checks the balance before sending and stops with an error telling you to empty the account. Sell the tokens, send them to another wallet, or burn them with spl-token burn <ACCOUNT> ALL, then run the close again. Burning cannot be undone, so check that the tokens are worthless first.
Can I use the spl-token CLI with my Phantom or Solflare wallet?
Not directly. The CLI signs with a keypair file, a hardware wallet such as a Ledger, or a seed phrase typed at a prompt. A browser wallet's key lives inside the extension. Importing a wallet's seed phrase into a terminal is possible but widens where your key exists, so a browser-based tool that asks your wallet to sign is usually the safer route for browser wallets.