Back to Blog
Solana

WithdrawExcessLamports on Solana: SPL Token and Token-2022 Guide

S
Sol Slugs Team
Sol Incinerator

Pricing and capability evidence checked September 3, 2026.

WithdrawExcessLamports is Token Program instruction 38. It solves a narrow problem: a mint, token account, or multisig can hold more lamports than it needs for rent exemption, but those lamports cannot move through an ordinary token transfer.

What does WithdrawExcessLamports do?

WithdrawExcessLamports moves only the SOL above a Token Program account's live rent-exempt minimum. The source remains open and its token or mint data stays unchanged. The required signer depends on whether the source is a token account, mint, or token multisig.

The instruction is available in both the classic SPL Token Program and Token-2022. It was useful for recovering lamports accidentally sent to token-owned accounts before the 2026 rent proposal. A lower rent minimum gives it a broader use: older accounts can retain their original balance while requiring a smaller reserve.

The authoritative behavior and current client example are in Solana's Withdraw Excess Lamports documentation. The processor implementation is also public in the Token Program repository.

Which accounts does the instruction require?

AccountWritable?Signer?Purpose
sourceYesSometimesToken account, mint, or multisig holding surplus lamports
destinationYesNoReceives the withdrawn lamports
authorityNoDepends on source typeProves permission to withdraw
multiSignersNoYes when usedSatisfy a configured token multisig threshold

The processor reads the source's data length and current rent settings, calculates its minimum balance, and transfers the difference. It does not accept a caller-supplied reserve that could be stale or manipulated.

Who must sign for each source type?

SourceRequired authority
Token account with a wallet ownerToken account owner
Token account owned by a token multisigRequired M-of-N multisig members
Mint with active mint authorityCurrent mint authority
Mint with no mint authoritySource mint account itself
Multisig source accountConfigured M-of-N members

The revoked-mint case deserves special attention. If the source mint was created from an on-curve keypair, that original keypair must sign. If it is off-curve, its controlling program must invoke the Token Program with the correct PDA signer seeds. A token holder or former mint authority cannot substitute for the source signature.

How do you build the instruction with the Solana client?

The current official example uses @solana-program/token with a configured @solana/kit client:

import { getWithdrawExcessLamportsInstruction } from "@solana-program/token";

const instruction = getWithdrawExcessLamportsInstruction({
    source,
    destination,
    authority,
});

await client.sendTransaction([instruction]);

Here authority is a TransactionSigner appropriate for the source. For a multisig authority, include its co-signers through multiSigners. Pin package versions in production and compile against the exact client release you use; client types can change even when the on-chain account contract does not.

Do not hardcode 0.00203928 SOL as the reserve. That is the legacy minimum for a standard 165-byte token account, not a universal current value. Query the current minimum for the source's actual data length immediately before building or previewing the transaction.

How do SPL Token and Token-2022 differ here?

The instruction's core effect is the same, but Token-2022 makes data-length assumptions especially risky. Mint and account extensions increase serialized size and therefore the required reserve. An integration that uses the standard 82- or 165-byte sizes for every source can overstate the surplus.

Token-2022's CPI Guard is another practical difference for wrappers. When the guard is locked, a cross-program invocation can be rejected even if the wallet would otherwise be a valid authority. Sol Incinerator skips those sources rather than placing one guaranteed failure into a larger cleanup transaction.

Native wrapped-SOL token accounts are rejected with NativeNotSupported. Unwrapping native SOL follows a different close-account path; it is not an excess-lamport withdrawal.

How does the Sol Incinerator API wrap the instruction?

Sol Incinerator's v2 API builds the Token Program call through Assetcinerator so the protocol and optional partner fees are enforced on-chain. This wrapper is a product layer; the raw Token Program instruction itself does not impose Sol Incinerator's fee.

Use the authenticated preview before asking a user to sign:

curl -X POST https://v2.api.sol-incinerator.com/withdraw-excess-lamports/preview \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "userPublicKey": "DESTINATION_WALLET",
    "sourceAccount": "TOKEN_ACCOUNT_MINT_OR_MULTISIG"
  }'

The related transaction and instruction routes are:

  • POST /withdraw-excess-lamports
  • POST /withdraw-excess-lamports-instructions

userPublicKey is the destination wallet and default authority. Supply authorityPublicKey when a different mint, source, or multisig authority must sign. Supply up to 11 multisigSignerPublicKeys when building a token-multisig flow. Every private key remains local; the API returns material for the required signers to approve.

The base protocol fee is 200 bps. A direct integrator can add a partnerFeeAccount and partnerFeeBps, while the normal Solana transaction fee remains separate. Use returned feeLamports and reclaim fields rather than reusing a cached percentage calculation.

Which failures should an integration handle?

  • No excess: source balance is already at the current reserve.
  • Wrong account owner or layout: source is not a supported Token Program account.
  • Invalid authority: the supplied signer does not match the decoded source state.
  • Incomplete multisig: too few valid configured signers were provided.
  • Native account: wrapped SOL uses another operation.
  • Locked CPI Guard: Token-2022 rejects wrapper CPI.
  • State changed: a balance, authority, or rent setting changed after preview.
  • Transaction cost exceeds value: a tiny withdrawal may not be economical after network fees.

Preview again when state may have changed, keep source selection idempotent, and never batch a known-ineligible source with otherwise valid work.

Sol Incinerator

Sol Incinerator

Preview live excess rent or use the v2 API to build a signer-safe withdrawal.

Try it now

Related Reading

Frequently Asked Questions

What does WithdrawExcessLamports do on Solana?

WithdrawExcessLamports transfers lamports above a Token Program account's current rent-exempt minimum to a destination wallet. Its source can be a token account, mint, or multisig. The instruction leaves token amounts, mint supply, authorities, extensions, and all other serialized account data unchanged.

Which authority signs WithdrawExcessLamports?

A token account uses its owner or configured multisig signers. A mint with an active mint authority uses that authority. A mint without one must sign as the source account itself, using its keypair or a CPI signer path from the program controlling an off-curve mint.

Does WithdrawExcessLamports support Token-2022?

Yes. The instruction is available for classic SPL Token and Token-2022 accounts, mints, and multisigs. Integrations must calculate rent from the source's actual data length because Token-2022 extensions can make accounts larger, and a locked CPI Guard can block wrapper-based execution.

Can WithdrawExcessLamports drain a token account below rent exemption?

No. The Token Program calculates the source's required minimum and transfers only the difference above it. Native wrapped-SOL token accounts are rejected. Applications should still preview live state because account balances, data lengths, rent settings, and available authority can change before submission.

WithdrawExcessLamports on Solana: SPL Token and Token-2022 Guide | Sol Incinerator