# Icrc1\_transfer from canister always returns InsufficientFunds: ledger\_balance=0 despite correct balance — both ICP and ckUSDC ledgers

**URL:** <https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201>\
**Category:** Developers\
**Tags:** icrc\
**Created:** [April 9, 2026, 1:03pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201 "2026-04-09T13:03:45Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![cog138](https://avatars.discourse-cdn.com/v4/letter/c/a9a28c/32.png) [@cog138](https://forum.dfinity.org/u/cog138)\
**Post date:** [April 9, 2026, 1:03pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/1 "2026-04-09T13:03:45Z")

</div>

Hi everyone,

I’m building an autonomous trading bot canister on ICP with Caffeine.AI and have been stuck on a persistent `InsufficientFunds: ledger_balance=0` error when calling `icrc1_transfer` from within the canister. I’ve exhausted all code-level fixes and would appreciate community insight.

**Canister ID:** `pbj3p-byaaa-aaaas-qadna-cai`

**The Problem:** `icrc1_balance_of({ owner = pbj3p-..., subaccount = null })` always returns the correct balance (2,250,000 for ckUSDC, 100,000,000 for ICP). But any `icrc1_transfer` call from the canister fails immediately with `InsufficientFunds: ledger_balance=0`.

**What I’ve ruled out (with proof):**

- ❌ Wrong subaccount — SHA224-computed Account ID matches IC Explorer To-address exactly

- ❌ Caller-derived subaccount problem — tested with `Timer.setTimer`, `caller_context=NONE(timer)` confirmed

- ❌ Cycles starvation — `cycles=1,116,788,978,000` (~1.1T), more than sufficient

- ❌ Canister frozen — `icrc1_name()` query call to the ledger succeeds fine

- ❌ ckUSDC-specific issue — same error on the ICP ledger (`ryjl3-...`)

- ❌ amount \< fee — tested with 50,000 base units (5x the fee)

- ❌ Pending/notify state — `account_balance` (legacy) and `icrc1_balance_of` both return identical values

- ❌ Pre-check `await` context switch — tested with transfer as the very first and only `await`

- ❌ Wrong Actor definition — using standard Motoko ICRC-1 actor interface

**Timer test result (key evidence):**

```auto
Timer fired | BACKEND_PRINCIPAL=pbj3p-byaaa-aaaas-qadna-cai
caller_context=NONE(timer)
balance_before=100000000
TRANSFER FAILED | error=InsufficientFunds: ledger_balance=0
amount=50000 | fee=10000

```

**Minimal Motoko code that fails:**

```auto
let ledger = actor("ryjl3-tyaaa-aaaaa-aaaba-cai") : actor {
  icrc1_transfer : (TransferArg) -> async TransferResult;
};
let result = await ledger.icrc1_transfer({
  from_subaccount = null;
  to = { owner = ownerPrincipal; subaccount = null };
  amount = 50000;
  fee = null;
  memo = null;
  created_at_time = null;
});
// Returns: Err(#InsufficientFunds { balance = 0 })

```

The canister has 1 ICP on `{ owner = pbj3p-..., subaccount = null }` confirmed by both legacy and ICRC-1 balance APIs. The transfer fails regardless of context (public shared func, timer callback, with or without pre-check).

Has anyone seen this before? Is there something about how a canister must be initialized or configured before it can send outgoing ledger transfers?

Any help appreciated.

---

<div class="post-metadata">

**Author:** ![mathiasb](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@mathiasb](https://forum.dfinity.org/u/mathiasb)\
**Post date:** [April 9, 2026, 1:10pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/2 "2026-04-09T13:10:54Z")

</div>

If you’re using Caffeine, could it be that the canister ID `pbj3p-byaaa-aaaas-qadna-cai` is the frontend canister, but it is the backend canister (that may not have any funds) that is making the call to the ledger?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [April 9, 2026, 1:29pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/3 "2026-04-09T13:29:32Z")

</div>

> [@cog138](#):
>
> `pbj3p-byaaa-aaaas-qadna-cai`

> **[Canister: pbj3p-byaaa-aaaas-qadna-cai](https://dashboard.internetcomputer.org/canister/pbj3p-byaaa-aaaas-qadna-cai)**
>
> Canister smart contract running on the Internet Computer blockchain.

It is an asset canister.

---

<div class="post-metadata">

**Author:** ![cog138](https://avatars.discourse-cdn.com/v4/letter/c/a9a28c/32.png) [@cog138](https://forum.dfinity.org/u/cog138)\
**Post date:** [April 9, 2026, 1:42pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/4 "2026-04-09T13:42:52Z")

</div>

Hello Mathias,

I’m pretty sure that `pbj3p-byaaa-aaaas-qadna-cai`is the backend canister, since I’ve been tinkering with it for a long time. I’ve currently used up 150 credits to move the transfer from the frontend to the backend so that something like an autonomous bot can work at all. Unfortunately, Caffeine V3 has now also reached its limit. That’s why I’m posting here.

I forwarded your question to Caffeine again, and received the following response:

> The canister ID `pbj3p-byaaa-aaaas-qadna-cai` is the **backend canister** , not the frontend. Here is the evidence:
> 
> - `debugSelfPrincipal()` returns `pbj3p-byaaa-aaaas-qadna-cai` from within the Motoko code — frontend canisters don’t expose Motoko functions like this
> 
> - `icrc1_balance_of({ owner = pbj3p-..., subaccount = null })` returns 2,250,000 base units of ckUSDC and 100,000,000 e8s of ICP — funds that were explicitly sent to this principal
> 
> - IC Explorer confirms incoming transfers **to** `pbj3p-byaaa-aaaas-qadna-cai` with `Source Canister = ryjl3-tyaaa-aaaaa-aaaba-cai` (the ICP ledger) and `xevnm-gaaaa-aaaar-qafnq-cai` (the ckUSDC ledger)
> 
> - The canister exposes backend functions like `executeBuyICP`, `debugTimerCallerTest`, `icrc1_balance_of` queries — these are all Motoko backend methods, not frontend asset serving
> 
> So the hypothesis — that `pbj3p-...` is the frontend canister while a separate, unfunded backend is making ledger calls — does not match the evidence. The funds are confirmed on `pbj3p-...`, and all Motoko logic (including the failing `icrc1_transfer` calls) runs on that same canister.
> 
> **However, the question does point to something worth double-checking:** it would be useful to explicitly confirm the frontend canister ID and verify that no logic accidentally runs there. On Caffeine, the frontend canister only serves static assets and should never be making inter-canister calls to ledgers.
> 
> The core issue remains: `icrc1_transfer` from `pbj3p-...` (the confirmed backend canister, with confirmed funds, confirmed cycles, confirmed timer context without user-caller) still returns `InsufficientFunds: ledger_balance=0`. That is the open and unresolved question.

---

<div class="post-metadata">

**Author:** ![ARLP](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/arlp/32/38585_2.png) [@ARLP](https://forum.dfinity.org/u/ARLP)\
**Post date:** [April 9, 2026, 3:59pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/7 "2026-04-09T15:59:24Z")

</div>

Its a crazy world huh

---

<div class="post-metadata">

**Author:** ![infu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/infu/32/11321_2.png) [@infu](https://forum.dfinity.org/u/infu)\
**Post date:** [April 9, 2026, 4:40pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/8 "2026-04-09T16:40:56Z")

</div>

Helmet guy provided a proof the other answers were correct

---

<div class="post-metadata">

**Author:** ![infu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/infu/32/11321_2.png) [@infu](https://forum.dfinity.org/u/infu)\
**Post date:** [April 9, 2026, 4:50pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/10 "2026-04-09T16:50:37Z")

</div>

My guess - user thinks: I’ve moved the transfer call from the frontend (js) to the backend (motoko). Takes the first id they can find - it’s the asset canister id.

But the asset canister hosts your frontend, it’s a static file server. It’s also ‘backend’, so you have two backend canisters, one serves files, the other is your custom motoko api.

---

<div class="post-metadata">

**Author:** ![cog138](https://avatars.discourse-cdn.com/v4/letter/c/a9a28c/32.png) [@cog138](https://forum.dfinity.org/u/cog138)\
**Post date:** [April 9, 2026, 5:29pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/12 "2026-04-09T17:29:08Z")

</div>

Yes, that’s my take on the whole thing as well. I’ve often asked myself why the system knows so little about fundamental things and has to do so much research just to try out all sorts of things afterward.

Well, it was definitely an interesting experiment for me. It could have worked. I would have liked to have had a small prototype to get a good kickstart into ICP development and then study the code.

But I think I’ll stick with my game in Unity DOTS and C# with Rider. That three-day of vibe coding with Caffeine was probably just procrastination anyway, putting off my game, which I’ve been working on for a few years now. The whole vibe coding thing isn’t for me anyway—it’s very tiring and kills any joy in development.

---

<div class="post-metadata">

**Author:** ![cog138](https://avatars.discourse-cdn.com/v4/letter/c/a9a28c/32.png) [@cog138](https://forum.dfinity.org/u/cog138)\
**Post date:** [April 9, 2026, 5:42pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/14 "2026-04-09T17:42:42Z")

</div>

Well, Caffeine confidently and convincingly assured me that this is how it’s supposed to work—a wallet in the canister that allows the canister to perform swaps on ICPSwap autonomously. That makes sense to me. Or does it not?  
And believe me, I definitely didn’t just grab the first ID that came to mind; I’ve now iterated on the problem 94 times with Caffeine. And now Caffeine itself has reached a dead end and assumes there’s a fundamental ledger issue or broken canister state, so it suggested “escalating” it here in the forum to get some help - which I did ;D

Well, screw it—it’s just playing around anyway.

---

<div class="post-metadata">

**Author:** ![ARLP](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/arlp/32/38585_2.png) [@ARLP](https://forum.dfinity.org/u/ARLP)\
**Post date:** [April 9, 2026, 5:46pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/15 "2026-04-09T17:46:35Z")

</div>

its not your fault its the cofee

---

<div class="post-metadata">

**Author:** ![Henn91](https://avatars.discourse-cdn.com/v4/letter/h/edb3f5/32.png) [@Henn91](https://forum.dfinity.org/u/Henn91)\
**Post date:** [April 9, 2026, 8:20pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/16 "2026-04-09T20:20:38Z")

</div>

> [@cog138](#):
>
> Well, screw it—it’s just playing around anyway.

Do you have github repo at caffeinepub. We could try to get it to work somehow.  
When i tested caffeine and built mixer, i had to get canister backend to be actor that can hold and transfer funds when called, most likely would work with timers as well. Lets say you get this working, next step is to get it working with ICPSwap, what i did try (just swaps, but failed).

I think for this to be built, CaffeineAI team has to teach AI to implement them correctly.

---

<div class="post-metadata">

**Author:** ![RootProof](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rootproof/32/40502_2.png) [@RootProof](https://forum.dfinity.org/u/RootProof)\
**Post date:** [April 9, 2026, 9:20pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/17 "2026-04-09T21:20:04Z")

</div>

T shirt worthy. Make this and make money

---

<div class="post-metadata">

**Author:** ![ARLP](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/arlp/32/38585_2.png) [@ARLP](https://forum.dfinity.org/u/ARLP)\
**Post date:** [April 9, 2026, 9:26pm UTC](https://forum.dfinity.org/t/icrc1-transfer-from-canister-always-returns-insufficientfunds-ledger-balance-0-despite-correct-balance-both-icp-and-ckusdc-ledgers/67201/18 "2026-04-09T21:26:32Z")

</div>

make website no shirt
