Blog

OpenCode "ECONNRESET: The socket connection was closed unexpectedly": Why It Started and How to Fix It

Short answer

Since October 29–30, 2026, many OpenCode users, mostly on internet providers in Russia (Rostelecom lines in Irkutsk, Perm and Ulyanovsk, and Dom.ru), get ECONNRESET: The socket connection was closed unexpectedly, or OpenCode sits with no output. Nothing changed on their side: no update, same account, and a Go or Go Plus subscription doesn't help. OpenCode tracks it in #60399, which is labeled reproduced, and has closed the other reports as duplicates of it.

According to the measurements in that issue, the provider's traffic filter silently drops the TLS handshake to opencode.ai (and on some lines models.dev) when the client offers a post-quantum key share. That key share makes the handshake about 1.5 KB. OpenCode runs on the Bun runtime, and Bun 1.4.1 and later send it by default, which is why curl still reaches opencode.ai from the same machine while OpenCode can't.

Ways to keep going:

  • Wait for a fix in OpenCode. None has shipped as of November 1, 2026. Follow #60399.
  • Use OpenCode 1.19.3. Users on affected lines report it works, because it is the last release built on the older Bun. It's a v1 build, so treat it as a stopgap.
  • Connect your own provider. Requests to your own API provider don't go to opencode.ai. TeamoRouter is one option; setup is below.

What the error looks like

text
ECONNRESET: The socket connection was closed unexpectedly. For more information, pass `verbose: true` in the second argument to fetch()

AI_APICallError: Cannot connect to API: ECONNRESET: The socket connection was closed unexpectedly.

Other forms of the same problem:

  • opencode run prints nothing for minutes. In the log, the server starts and lists providers and models, then there is no session or stream line (#60399).
  • OpenCode Desktop shows the raw ECONNRESET while it retries the failed request (#60680).
  • The opencode.ai website stops loading as well (#60573).

Check whether it's this problem

Run this in a terminal while OpenCode is failing:

bash
curl -sS -o /dev/null -w "%{http_code}\n" https://opencode.ai/inference/v1/models

On Windows, use curl.exe -sS -o NUL -w "%{http_code}" https://opencode.ai/inference/v1/models.

If it prints 200 while OpenCode still fails, it's this filter: curl sends a small handshake that gets through. If curl fails too, your connection to opencode.ai is down in general, and the cause is something else.

Why it happens

The people affected measured it in #60399:

  • What gets dropped. A TLS handshake carrying the post-quantum key share X25519MLKEM768 is about 1.5 KB and doesn't fit in one network packet. On affected lines, such handshakes to opencode.ai and models.dev never get an answer, while the same handshake to github.com or registry.npmjs.org goes through. A handshake without the post-quantum part reaches opencode.ai fine. So the filter depends on both the destination and the handshake.
  • Why it hit OpenCode on one day. Commenters traced it to the Bun runtime bundled in OpenCode. OpenCode 1.19.3 is the last release on Bun 1.3.14, which sends a handshake of about 500 bytes. OpenCode 1.19.4 and every v2 release use Bun 1.4.x, which sends the larger one. On these lines the filter started matching on October 29–30, and commenters believe the rule was deployed centrally overnight.
  • It's not specific to OpenCode. Chrome 124 and later, which also send the post-quantum key share, fail to open opencode.ai on the same lines.
  • Retrying doesn't help. In one commenter's test, 8 of 8 attempts with the default handshake failed, while every attempt without the post-quantum key share succeeded.

OpenCode's support bot reproduced the hang: when the handshake stalls, OpenCode waits silently, as if the model were slow, instead of reporting a network error. The default header timeout is about five minutes, and after it OpenCode opens a new connection and waits again.

What to do

  1. Follow #60399. Commenters proposed a setting to turn off the post-quantum key share, or a retry without it when a handshake stalls, and OpenCode's bot noted the first as an improvement for the maintainers to consider. As of November 1, 2026, no fix has been released.
  2. Try another network. Users report that OpenCode works over a VPN, because the filter can't see the handshake inside the tunnel. One Dom.ru user said a VPN didn't help, so results vary by line.
  3. Use OpenCode 1.19.3 as a stopgap. In #60534, a user on an affected line installed 1.19.3 and OpenCode worked again, and another commenter confirmed that 1.19.3 still answers with a free model. It's a v1 release and OpenCode is moving everyone to v2, so check #60399 before relying on it. Install it with npm install -g opencode-ai@1.19.3.
  4. Connect your own provider. OpenCode sends requests for a custom provider to that provider's own address, not to opencode.ai. TeamoRouter's API at api.teamorouter.com isn't affected: OpenCode requests from our Russian-speaking users kept arriving after October 30, and their number went up rather than down.

Keep coding with TeamoRouter

New accounts start with a $0 balance — top up before your first request. Top up from $5. If a request returns 402 (400 on the OpenAI format, which OpenCode uses) with "wallet balance is insufficient", your balance is empty — your base URL and key are fine. Top up and retry.

TeamoRouter gives you one key for GPT, Gemini, DeepSeek, Kimi, GLM and Claude, billed per token from a prepaid balance. There's no subscription; top up from $5 by card or with USDT, USDC or ETH (how to pay with USDT).

  1. Create an API key in the TeamoRouter console.
  2. Add a provider to ~/.config/opencode/opencode.json (all projects) or opencode.json in your project:
json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "teamorouter": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "TeamoRouter",
      "options": {
        "baseURL": "https://api.teamorouter.com/v1",
        "apiKey": "{env:TEAMOROUTER_API_KEY}"
      },
      "models": {
        "gpt-6.1-sol": { "name": "GPT 6.1 Sol" },
        "deepseek-flash-1017": { "name": "DeepSeek V4.1 Flash 1017" },
        "kimi-k3.1-pro": { "name": "Kimi K3.1 Pro" },
        "glm-5.3": { "name": "GLM-5.3" }
      }
    }
  }
}

This is the custom provider format from the OpenCode 1 docs, and OpenCode 2 still reads it, according to its migration guide.

  1. Give OpenCode the key:
bash
export TEAMOROUTER_API_KEY="your TeamoRouter API key"

OpenCode 2 sends requests from a shared background server, so give the variable to that server with opencode service set env TEAMOROUTER_API_KEY "your key" (docs).

  1. Run /models and pick a TeamoRouter model. To make it the default, add "model": "teamorouter/gpt-6.1-sol" to the config.

In OpenCode Desktop, add the same provider under Settings → Server → Providers → Custom provider; see Connect OpenCode to TeamoRouter. For Claude models, use Claude Code instead: this provider uses the OpenAI protocol and can miss Claude's prompt cache.

FAQ

Is my OpenCode account blocked? No. The connection is dropped during the TLS handshake, before any request reaches OpenCode, so your account and subscription are never involved. The commenters who measured it in #60399 and #60534 say the same.

Will a Go or Go Plus subscription fix it? No. Go models are served from opencode.ai too, so they fail the same way.

Why does curl work but OpenCode doesn't? curl sends a small handshake without the post-quantum key share, and the filter lets that through.

Does updating OpenCode help? Not yet. Every v2 release so far uses the newer Bun runtime. Watch #60399 for a release that adds a way to turn off the post-quantum key share.

Next steps

Ready to connect?Log in · top up · create an API key — three steps to start.