Bounce / non-bounce message
TON message flag that controls what happens on receiver failure. Bounceable — funds return to sender; non-bounceable — funds stay at the destination even if no contract is there yet.
Aliases: bounceable, non-bounceable, bounce flag
Every internal message on TON carries a bounce flag. It determines what happens when the receiving contract either does not exist (uninitialised), runs out of gas, or rejects the message: funds either return to the sender or stay at the destination.
The flag has three production values you’ll actually meet: bounceable, non-bounceable, and a special “bounce-back” message that is automatically produced when a bounceable message fails.
Bounceable (default for contract calls)
If a contract sends a bounceable message and the destination fails to process it (no code deployed, exception, out-of-gas):
- The remaining TON value is returned to the sender (minus a small forward fee).
- A bounce message is generated automatically — the sender’s contract can listen for it and react.
- This is the safe default for inter-contract calls: if you send funds and the recipient logic fails, you don’t lose the funds.
In TON addresses, a bounceable destination is encoded with the EQ... prefix (raw 0: form, with bounceable flag set in the user-friendly form).
Non-bounceable
If a contract sends a non-bounceable message and the destination fails:
- The TON sticks at the destination address regardless of contract state.
- No bounce-back is produced.
This is what you want when sending to a brand-new wallet that hasn’t been deployed yet. If the message were bounceable, the brand-new wallet would have no code, processing would fail, and funds would return — the user would never receive their TON.
In addresses, non-bounceable is the UQ... prefix.
Why this matters in wallets
Wallets handle the flag automatically:
- Sending to a known, deployed wallet: bounceable is fine; the wallet’s
recv_internalaccepts the value. - Sending to a fresh wallet (never received TON before): wallets switch to non-bounceable so the funds land even before the receiver’s contract is initialised.
- Sending to a contract (DEX router, jetton master): bounceable is the right choice — if the call is malformed, the funds bounce back.
When a user pastes an address copied from somewhere, the prefix encodes the intended bounce flag. Wallets will usually warn if it looks wrong.
What developers need to remember
recv_internalshould handle both — your contract code receives both bounceable and non-bounceable messages. The first 32 bits of the message body indicate whether it’s a bounce response (0xfffffffffor a bounce-back) or an ordinary message (any other op-code).- Always handle bounce-backs for any outgoing payment. Otherwise, if your downstream call fails, the returned funds will sit in your contract and you’ll have to add explicit logic to track them.
- Send to wallets non-bounceable if you cannot guarantee the wallet has been deployed. Most user-facing flows do this by default.
Why TON has this at all
In synchronous chains (Ethereum), a failed call simply reverts the whole transaction — the sender keeps the funds because the entire call atomically rolls back. TON is asynchronous: by the time the receiver fails, the sender’s part of the transaction has already committed. Bounce-back is the protocol-level mechanism that recovers funds from the receiver’s failed transaction back to the sender’s account, in a separate block.
It is one of the more confusing aspects of TON for developers coming from EVM, and one of the most common sources of “where did my TON go?” support questions.