All posts
8 min read

TON Liteserver "Not Ready" — Why It Happens and How to Fix It

TON liteserver returning "not ready" or ADNL timeouts? Here's why public-config nodes fail and how retries plus a TONNode hosted key fix it.

TONliteserverADNLnot readyMCPTON nodes

Liteserver not ready: you sent a trivial request — and got "not ready" back

You're building an agent that needs to check a wallet balance or call a contract get-method. The code is correct, the address is correct, the liteserver config comes straight from the official global-config.json. Yet instead of an answer you keep getting either not ready or nothing at all — the connection just hangs and dies with an ADNL timeout. And it doesn't even reproduce consistently: works in the morning, fails under load. Sound familiar? This isn't a bug in your code, and TON isn't down either. It's the predictable behavior of the public liteservers in the global config. Let's break down why TON liteserver not ready happens, what actually helps on the client side — and what doesn't.

What "not ready" and ADNL timeouts mean on a TON liteserver

not ready is the liteserver telling you directly: "I'm not synced yet, I can't answer." TON has two blockchain layers: the masterchain and the basechain (workchain 0), which is split into shardchains, or shards. The masterchain is like a book's table of contents; the shards are the chapters themselves, holding transactions and account state. A node often receives the masterchain head before it has caught up with the corresponding shard blocks. At that moment the masterchain is ahead of the basechain, while your account's state lives in the latest shard block — which can't be verified yet. So the node honestly replies not ready instead of handing you stale or incomplete data.

An ADNL timeout is another symptom of the same disease. ADNL is TON's native transport protocol — it's how a liteserver talks to a client (there's no HTTP involved at all). When the node is overloaded, it simply doesn't answer the ADNL request within the allotted window, and the client bails out on timeout before your business logic ever runs.

It's important not to mix up the layers here. not ready and ADNL timeouts live at the level of the liteserver's native ADNL protocol. That is not the same thing as HTTP 429 Too Many Requests, which HTTP gateways like toncenter and tonapi.io return when you exceed a rate limit. Different layers, different codes, different causes. If 429 is what you're actually fighting, that's a separate story: the toncenter 429 fix write-up. And the "error 228" meme from TON chats is a community joke, not a real code — no liteserver ever responds with it.

Why public liteservers from the global config fall over under load

The root cause is mundane. The liteservers in ton.org/global-config.json are shared and rate-limited. It's a public resource hit simultaneously by thousands of developers, bots, indexers, and agents worldwide. A resource like that has three systemic constraints:

  • Shared load. You share the pool with the entire ecosystem. At peak, a node either can't keep up with the head of the network (hence not ready) or simply doesn't respond in time (ADNL timeout).
  • No deep history. Public nodes don't keep a deep archive. If you need an old transaction by its lt/hash pair, it may already be gone — there's a separate piece on lt and hash covering historical lookups.
  • No guarantees. It's provided as-is. You have no priority, and nobody promises you any throughput: lucky today, unlucky tomorrow.

In other words, not ready isn't random noise you can "wait out" — it's the natural behavior of a shared resource under load. And no amount of code on your side will make someone else's overloaded node sync faster.

Client-side fixes: retries, endpoint rotation, and timeouts

Before touching your infrastructure, squeeze everything you can out of the client. These techniques genuinely work, but they have a ceiling — the nodes are still shared.

1. Retries with exponential backoff

not ready is often transient: 200–800 ms later the same liteserver has applied the shard block it was missing. A simple retry with a growing delay clears a noticeable share of these errors.

async function withRetry<T>(fn: () => Promise<T>, tries = 4): Promise<T> {
  let lastErr: unknown;
  for (let i = 0; i < tries; i++) {
    try {
      return await fn();
    } catch (e) {
      lastErr = e;
      // retry 'not ready' and ADNL timeouts, but not business errors
      await new Promise((r) => setTimeout(r, 200 * 2 ** i));
    }
  }
  throw lastErr;
}

2. Endpoint rotation

Keep several liteservers from the config in a pool and switch to the next one when the current one returns not ready or times out. One node may be lagging while its neighbor has already caught up.

3. A more generous timeout

The default ADNL timeout is sometimes too tight for an overloaded public node. A small buffer (a few seconds) reduces false disconnects. But cranking the timeout toward infinity just piles up hanging requests — that's anesthesia, not treatment.

One more useful trick: a lightweight healthcheck before the real request. get_masterchain_info (the masterchain head) is perfect for this — it's the first operation to return a fresh seqno once the node has caught up with the head of the network, and it only returns not ready when the node hasn't even caught up with the masterchain head itself. Got a fresh seqno? The node is up — safe to call get_account_state, get_balance, run_get_method.

The honest takeaway: retries + rotation + timeouts push the error rate down, but they don't remove the cause. Public nodes are overloaded by design — you're just knocking more politely on a door with the same queue behind it. Other ways to reach TON data are covered in the 2026 toncenter alternatives overview.

The fix without running your own node: a TONNode hosted key on our liteserver

There's only one way to kill not ready for good — stop hitting shared nodes. Running and maintaining your own TON node is expensive and tedious: syncing, disk, updates, monitoring. The middle ground is to skip the shared pool and get guaranteed throughput with priority access through a key.

TONNode is a hosted MCP server for TON. MCP (Model Context Protocol) is the standard that AI agents (Claude, Cursor, ChatGPT/Codex, any MCP client) use to call tools. Instead of your code parsing the global config and dancing around not ready, the agent calls a ready-made tool, and behind it sits the hosted endpoint https://mcp.tonnode.io/mcp with your Bearer key. That's guaranteed throughput instead of a shared queue.

The @tonnode/mcp package — open source (MIT, on npm and GitHub as tonnode/mcp) — runs over TON's native ADNL protocol, with no HTTP middle layers. You're not trading your transport for a slow HTTP gateway; you stay on the same honest ADNL — but with priority access under your own key.

For diagnostics and everyday reads, these are the ones you'll reach for:

  • get_masterchain_info — the masterchain head, a natural healthcheck.
  • get_account_state — account status, flags, and the last transaction.
  • get_balance — balance in GRAM.
  • run_get_method — any read-only contract get-method.

If you're just getting started with MCP on TON, work through the MCP for TON guide.

How to connect: npx locally or the hosted endpoint with a key

Free, locally

The full set of read tools works locally out of the box, over the public config, with no card and no key:

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

Great for development and local experiments. But keep in mind: local npx still hits the same shared liteservers under the hood, so it won't save you from not ready under load — what it saves you from is dependency wrangling, while giving you a unified tool interface.

Hosted with a key

To get off the shared nodes, switch the transport to HTTP-MCP with your own Bearer key (the actual tool calls go to our node over ADNL):

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

What it looks like with an agent

Once connected, a plain prompt is all the agent needs — it picks the tools itself:

First get_masterchain_info as a healthcheck. Then get_account_state for EQC… — show me the status and the last transaction. Then get_balance for the same address.

Under the hood that's a chain: get_masterchain_info (node is alive and caught up with the head) → get_account_state (status, flags, last transaction) → get_balance (GRAM balance). No retries around somebody else's queue — the request goes out on guaranteed throughput. By the way, GRAM is the renamed Toncoin (the rename happened in June 2026); the network is still called TON.

A free Hobby key (60 requests/min) is issued right after sign-in, no card required. Then, as you grow: Pro — $29/mo, 300 requests/min; Scale — $199/mo, 1200 requests/min. One important detail: every plan includes all 16 TONNode tools — you only pay for throughput, never for functionality.

Your own dedicated liteserver — by request, not self-serve

Sometimes a hosted plan isn't enough and you need a dedicated (single-tenant) liteserver — serving only your traffic, with no neighbors at all. That option exists, but let's be honest: it is not self-service. There's no "enable single-tenant" button in the dashboard — we set it up by hand, so get in touch and we'll talk through your load and configuration.

And one more honest caveat about history depth. The TONNode archive node is still syncing and does not serve requests yet. "Archive depth" is a roadmap item, not a shipped feature. If deep full-history access is critical for you today, plan for it separately. What's ready and what's coming is on the roadmap.

TL;DR

  • not ready = the node isn't synced: the masterchain is ahead of the shard, and the account state in the latest shard block can't be verified yet.
  • Public liteservers from the global config are shared and rate-limited: not ready, ADNL timeouts, no deep history. Don't confuse this with HTTP 429 from toncenter/tonapi — that's a different layer.
  • Client-side fixes (retries with backoff, endpoint rotation, timeouts) lower the error rate but don't remove the cause.
  • get_masterchain_info is your healthcheck: it only flashes not ready when the node hasn't caught up with the masterchain head at all.
  • The real cure is moving off the shared resource onto guaranteed throughput.

Grab a free Hobby hosted key and stop catching "not ready" on shared nodestonnode.io/dashboard?plan=hobby

As your load grows — pricing and roadmap.

Give your agent TON access

16 MCP tools: reads, non-custodial swaps, cross-chain and wallets. Free tier — 60 req/min, no card required.