Key takeaways
- A Token-2022 token account is closed with the same CloseAccount instruction as a classic SPL token account, and it returns its whole rent deposit, typically 0.00151 to 0.00158 SOL, or 0.00207 to 0.00216 SOL if opened before the rent cut.
- Token-2022 accounts are larger than the 165-byte SPL token account because each extension adds bytes: a plain associated account is 170 bytes and one for a transfer-fee token is 182 bytes.
- The Token-2022 program refuses to close an account while it holds withheld transfer fees, but anyone can harvest those fees to the mint first, after which the account closes normally.
- The spl-token CLI's gc command works on one token program at a time, so cleaning Token-2022 accounts from the terminal needs the --program-2022 flag.
- Non-transferable Token-2022 tokens cannot be sold or sent, but the holder can burn them and then close the account to recover its rent.
The short answer
You close a Token-2022 account the same way as a classic SPL token account: empty it, then send CloseAccount to the Token-2022 program, and the full rent deposit comes back. A typical one returns 0.00151 to 0.00158 SOL, or 0.00207 to 0.00216 SOL if opened before Solana lowered rent. Two extra conditions apply: withheld transfer fees must be harvested to the mint first, and confidential balances must be empty.
How is closing a Token-2022 account different from closing an SPL token account?
The instruction and the outcome are the same; the differences are where the accounts live and what can block them. Token-2022 is a separate program at TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb, next to the classic SPL Token program at TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA. Each token account belongs to one of them for life, and a close instruction has to go to the program that owns the account.
Reading the Token-2022 source, its CloseAccount checks everything the classic program checks, plus three extension conditions:
- The token balance is zero, except for wrapped SOL. Same as the classic program.
- The signer is the owner, or the close authority if one is set. Same as the classic program.
- Withheld transfer fees are zero, for tokens with the transfer fee extension.
- The confidential balance is zero, for accounts configured for confidential transfers, including any confidential withheld fees.
- CPI Guard allows it. If you enabled CPI Guard on the account, a program calling the close on your behalf must send the rent to you. A close you sign directly is not affected.
If those hold, the account is deleted and every lamport in it goes to the destination you name. The general safety picture is the same as for any token account, covered in is it safe to close Solana token accounts.
Why do Token-2022 accounts hold more rent?
Token-2022 accounts hold more rent because they are larger. Rent is (128 + bytes) x 5,080 lamports at today's rate, and 6,960 lamports per byte before Solana lowered it. A classic SPL token account is always 165 bytes. A Token-2022 account adds one byte for the account type and then a 4-byte header plus the data for each extension. Associated token accounts always carry the immutable owner extension, which is why the smallest common Token-2022 account is 170 bytes.
Some extensions on the mint force a matching extension onto every holder's account. The sizes below follow from the Token-2022 source for associated token accounts:
| Account | Size | Rent if opened recently | Rent if opened before the change |
|---|---|---|---|
| Classic SPL token account (for comparison) | 165 bytes | 0.00148844 SOL | 0.00203928 SOL |
| Token-2022, no mint extensions that touch accounts | 170 bytes | 0.00151384 SOL | 0.00207408 SOL |
| Non-transferable or pausable token | 174 bytes | 0.00153416 SOL | 0.00210192 SOL |
| Token with a transfer hook | 175 bytes | 0.00153924 SOL | 0.00210888 SOL |
| Token with a transfer fee | 182 bytes | 0.0015748 SOL | 0.0021576 SOL |
| Configured for confidential transfers | about 469 bytes or more | about 0.0030 SOL or more | about 0.0042 SOL or more |
The difference per account is small, a few hundred thousand lamports at most for common cases, but closing returns whatever the account actually holds. For any other size, the free rent calculator gives the deposit from a byte count, and the rent-exempt minimum for every account type includes Token-2022 mints too. Totals across a whole wallet are worked through in how much SOL you can recover from token accounts.
How do you find your Token-2022 accounts?
You find them by querying the Token-2022 program for your address, not only the classic program. That sounds obvious, but it is the most common reason Token-2022 accounts are missed. A script or tool that calls getTokenAccountsByOwner with only the classic program ID will never see them.
Three ways that work:
- A block explorer. Open your wallet address and look at its token accounts. Explorers generally show both programs and include zero-balance accounts, which wallet apps tend to hide.
- The CLI.
spl-token accountsin current versions lists accounts from both programs. If your installed version shows only classic accounts, runspl-token accounts --program-2022. - A scan that covers both programs. Connect your wallet to the SOLTidy Token Account Closer. The scan only reads: it queries the SPL Token and Token-2022 programs in parallel and labels each account with its program, and nothing is signed until you press Claim.
Wallet apps are built to show what you hold, so an empty account usually disappears from the token list while its rent deposit stays on chain. That applies to both programs, but Token-2022 accounts for unusual extensions, such as non-transferable or confidential tokens, are also the ones wallets are least likely to display well.
How do you close a Token-2022 account with withheld transfer fees?
Harvest the withheld fees to the mint, then close; both can go in one transaction. On a transfer-fee token, every transfer you receive leaves the fee sitting in a withheld field of your account. Those tokens are not yours to spend; they belong to the token's fee mechanism. The program refuses to close the account until the field is zero, with the error "An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again".
The fix is HarvestWithheldTokensToMint. It is permissionless: any wallet can call it for any accounts of that mint, because it only moves the withheld amount into the mint's own withheld field and cannot redirect it. Once harvested, the account closes normally.
- With the CLI,
spl-token close --address <ACCOUNT>already does this. Reading the CLI source, if the account has withheld fees it sends a harvest transaction first and then the close. - With SOLTidy, the closer adds the harvest instruction in front of
CloseAccountfor any account that holds withheld fees, in the same transaction. You do not need to do anything extra.
If you created a transfer-fee token yourself, collecting those fees as the withdraw authority is a different job, done with the Claim Transfer Fees tool or spl-token withdraw-withheld-tokens, and covered step by step in how to set and claim Token-2022 transfer fees. As a holder you only need the harvest.
Can you close frozen, non-transferable or confidential Token-2022 accounts?
Mostly yes, with conditions that depend on the extension. The cases:
- Frozen accounts. A frozen account with a balance is stuck: burning and transferring both fail with "Account is frozen", and only the freeze authority can thaw it. An empty frozen account is a different matter. Neither token program's
CloseAccountchecks the frozen flag in the current source, so the owner should be able to close it withspl-token close --address. Tokens with the default account state extension create every new account frozen, so this case is more common on Token-2022. SOLTidy does not list frozen accounts at the moment, andspl-token gcskips them. - Non-transferable tokens. These cannot be sent or sold, but the program lets the holder burn them. Burn, then close. Burning is permanent.
- Paused tokens. A mint with the pausable extension can pause transfers, minting and burning. While paused, a balance cannot be burned, so a non-empty account cannot be emptied. An already empty account still closes.
- Confidential transfer accounts. The encrypted balance and any pending balance must be zero before closing. Emptying them means
spl-token apply-pending-balanceandspl-token withdraw-confidential-tokens, which generate zero-knowledge proofs. Few tools support this, and SOLTidy currently skips any account configured for confidential transfers. - Transfer hooks and permanent delegates. Neither blocks closing. A hook runs on transfers, not on burns or closes.
If a balance has any value, sell it before burning. Sell Dust for SOL quotes through Jupiter, and a transfer-fee token's quote already reflects the fee. Before buying a Token-2022 token in the first place, a rug check shows its extensions, and the extensions themselves are explained in Token-2022 explained for traders.
How do you close Token-2022 accounts with the spl-token CLI?
The CLI is free beyond network fees and handles Token-2022 well, provided you know which commands look at which program. It needs your key as a keypair file, which most browser-wallet users do not have and should not create casually. The general walkthrough for both programs, including setup, is in closing Solana token accounts with the CLI.
- List accounts:
spl-token accounts(add--program-2022if your version shows only classic ones). - Close one account:
spl-token close --address <ACCOUNT>. The CLI reads the owning program from the address and harvests withheld fees first if there are any. - Close all empty associated accounts for Token-2022:
spl-token gc --program-2022 --close-empty-associated-accounts. Without--program-2022, gc only looks at classic accounts. Without--close-empty-associated-accounts, it does not close associated accounts at all. - Recover excess rent from older accounts you keep:
spl-token withdraw-excess-lamports <ACCOUNT> <RECIPIENT>.
One caveat from reading the source: gc closes empty accounts directly and does not harvest withheld fees first, so an account of a transfer-fee token with withheld fees will fail inside gc. Close those individually with spl-token close.
How does SOLTidy handle Token-2022 accounts?
I built the closer to treat both programs as one list, because that is how wallets look to their owners. Specifically, from the code:
- One scan queries SPL Token and Token-2022 together and reads each account's real lamport balance, so the figure shown is what the extension-sized account actually holds.
- Empty accounts are pre-selected. Non-empty ones can be added by hand, which burns the balance before the close.
- Withheld transfer fees are harvested to the mint in the same transaction as the close.
- Accounts you keep that were opened before the rent change get their excess withdrawn with
WithdrawExcessLamports, about 0.00056 to 0.00059 SOL per Token-2022 account, without closing them. That is covered in getting SOL back without closing token accounts. - Frozen accounts, accounts with someone else as close authority, and confidential transfer accounts are left out, because they would fail.
- Up to 12 items go in a transaction, every batch is simulated before you sign, and anything that changed since the scan is dropped.
The fee is 5% of the rent recovered, charged per transaction inside that transaction, and nothing if nothing is recovered. It asks for no token approvals and works with any Solana wallet. For a few accounts, the CLI does the same job for network fees alone. When a close fails for a reason not covered here, why you can't close a Solana token account lists the exact errors and fixes.
Bottom line
Closing a Token-2022 account is the classic close with a little more to check. Query the Token-2022 program so you actually find the accounts, harvest withheld transfer fees before the close, empty any confidential balance, and burn non-transferable leftovers if you do not want them. Each account returns its full deposit, slightly more than a classic token account because extensions make it bigger. Use spl-token close or gc with --program-2022 if you live in a terminal, or let the Token Account Closer scan both programs and handle the harvest for you.
Questions & answers
How much SOL do I get back from closing a Token-2022 account?
The whole rent deposit, which depends on the account's size and age. A plain Token-2022 associated token account is 170 bytes and returns 0.00151384 SOL, or 0.00207408 SOL if it was opened before Solana lowered rent. An account for a transfer-fee token is 182 bytes and returns 0.0015748 or 0.0021576 SOL. Accounts configured for confidential transfers are much larger and return about 0.003 SOL or more.
Why can't I close my Token-2022 account even though the balance is zero?
Usually because it holds withheld transfer fees. On a token with the transfer fee extension, fees from incoming transfers sit in a separate withheld field of your account, and the program rejects CloseAccount until that field is zero. Harvesting the fees to the mint is permissionless, so you can do it yourself in the same transaction as the close. A confidential balance that is not empty blocks closing too.
Do I need the --program-2022 flag to close Token-2022 accounts with the CLI?
For spl-token close, usually not: current versions read the owning program from the account or mint address you pass. For spl-token gc you do, because gc scans one program at a time and defaults to the classic SPL Token program. Run spl-token gc --program-2022 --close-empty-associated-accounts to include Token-2022 associated accounts.
Can I close the account of a non-transferable (soulbound) token?
Yes, once it is empty. Non-transferable tokens cannot be sent or sold, but Token-2022 still lets the holder burn them. Burn the balance, then close the account and the rent deposit returns to you. Burning is permanent, so only do it if you are sure you do not want the token, for example a credential you no longer need.
Why don't my Token-2022 accounts show up in my wallet or in some cleanup tools?
Two reasons. Wallets generally hide tokens with a zero balance, so empty accounts drop out of view while still holding rent. And a tool or command that only queries the classic SPL Token program will never see Token-2022 accounts, because they belong to a different program. A scan must query both program IDs to find everything.
Does closing a Token-2022 account trigger the token's transfer hook or transfer fee?
No. CloseAccount moves only SOL, not tokens, so no transfer fee applies and the transfer hook program is not called. Burning a balance before the close does not call the hook or charge the fee either. The hook and the fee matter when you sell or send the tokens, not when you burn them or close an empty account.