Skip to content

deepseek-v4-flash-free (zen) 429 FreeUsageLimitError on EVERY request from 3 distinct IPs, with and without official client headers #42074

Closed as duplicate

Description

@cubelitblade

Summary

When calling https://opencode.ai/zen/v1/chat/completions with model deepseek-v4-flash-free using plain curl (or any non‑official HTTP client), every direct API request I tried returns HTTP 429:

{"type":"error","error":{"type":"FreeUsageLimitError","message":"Error from provider (Console): Rate limit exceeded. Please try again later."}}

However, the official OpenCode TUI (opencode CLI) works fine from the same network environment.

Environment

  • opencode version: 1.18.16
  • Platform: FedoraLinux-44 (WSL on Windows 11), terminal: Windows Terminal
  • Provider: opencode / model deepseek-v4-flash-free

Steps to reproduce

  1. POST to https://opencode.ai/zen/v1/chat/completions (also /responses) with Authorization: Bearer <valid key>, model=deepseek-v4-flash-free.
  2. Observe HTTP 429 with body:
    {"type":"error","error":{"type":"FreeUsageLimitError","message":"Error from provider (Console): Rate limit exceeded. Please try again later."}}
  3. Repeat from different network origins and with official headers.

What I verified

  • Tried three distinct exit IPs (AWS proxy, direct IPv4, direct IPv6) – all get 429 immediately, no IP‑based blocking.
  • Also tested with OpenCode-related headers such as:
    • x-opencode-client
    • x-opencode-version

Key observation

The official OpenCode TUI succeeds while direct OpenAI-compatible API calls fail consistently.

This suggests that there may be a difference in:

  • endpoint routing,
  • authentication flow,
  • request headers,
  • or backend handling between the TUI and direct API usage.

Activity

  1. github-actions commented on Aug 12, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is distinct (e.g., a different root cause or a new regression), please add a note explaining how it differs from the above.

  2. 12errh commented on Aug 13, 2026

    @12errh

    @cubelitblade

    Root Cause

    The issue is triggered by the User-Agent header, not the API key or IP address. The upstream "Console" inference provider (which serves the -free models) gates anonymous free capacity strictly based on this header:

    • TUI request (User-Agent: opencode/<version>) → 200 OK
    • Custom request (User-Agent: curl/8.0 or any non-opencode UA) → 429 FreeUsageLimitError

    Testing confirmed that x-opencode-client, x-opencode-version, and session headers alone do not unlock the capacity. Only the User-Agent value matters.

    According to the source code (packages/opencode/src/session/llm/request.ts), the TUI always sends User-Agent: opencode/<version>. The gateway strips all x-opencode-* headers before forwarding upstream but passes the User-Agent through untouched, allowing the upstream provider to use it for free-pool validation.


    Fix

    Set the opencode User-Agent directly on your request:

    curl -s https://opencode.ai \
      -H "Authorization: Bearer <key-or-public>" \
      -H "Content-Type: application/json" \
      -H "User-Agent: opencode/1.18.16" \
      -d '{"model":"deepseek-v4-flash-free","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'

    Verified: Including the opencode/ UA returns an HTTP 200 (including streaming). Excluding it results in a 429 error, regardless of IP or key.


    Notes

    • This restriction only affects -free models. Paid and balance-backed models are not gated by the User-Agent.
    • This is an anti-abuse gate designed to reserve free capacity for the official client. Because of this, it may change at any time. For long-term stability, it is better to Bring Your Own Key (BYOK) with a non-free model.
    • If you are writing a custom client, inject User-Agent: opencode/<version> into the request. Please also forward the user's real IP so per-IP quotas remain fair.
    • The solution i make is this simple proxy https://github.com/12errh/zen-proxy it just change the agent header line so it can work.
  3. zqy1-1 commented on Aug 15, 2026

    @zqy1-1

    Thank you

    Fix

    Set the User-Agent directly on your request:opencode

    curl -s https://opencode.ai
    -H "Authorization: Bearer "
    -H "Content-Type: application/json"
    -H "User-Agent: opencode/1.18.16"
    -d '{"model":"deepseek-v4-flash-free","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'
    Verified: Including the UA returns an HTTP 200 (including streaming). Excluding it results in a 429 error, regardless of IP or key.opencode/

  4. cubelitblade commented on Aug 15, 2026

    @cubelitblade
    Author

    @cubelitblade

    Root Cause

    The issue is triggered by the User-Agent header, not the API key or IP address. The upstream "Console" inference provider (which serves the -free models) gates anonymous free capacity strictly based on this header:

    • TUI request (User-Agent: opencode/<version>) → 200 OK
    • Custom request (User-Agent: curl/8.0 or any non-opencode UA) → 429 FreeUsageLimitError

    Testing confirmed that x-opencode-client, x-opencode-version, and session headers alone do not unlock the capacity. Only the User-Agent value matters.

    According to the source code (packages/opencode/src/session/llm/request.ts), the TUI always sends User-Agent: opencode/<version>. The gateway strips all x-opencode-* headers before forwarding upstream but passes the User-Agent through untouched, allowing the upstream provider to use it for free-pool validation.

    Fix

    Set the opencode User-Agent directly on your request:

    curl -s https://opencode.ai
    -H "Authorization: Bearer "
    -H "Content-Type: application/json"
    -H "User-Agent: opencode/1.18.16"
    -d '{"model":"deepseek-v4-flash-free","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'
    Verified: Including the opencode/ UA returns an HTTP 200 (including streaming). Excluding it results in a 429 error, regardless of IP or key.

    Notes

    • This restriction only affects -free models. Paid and balance-backed models are not gated by the User-Agent.
    • This is an anti-abuse gate designed to reserve free capacity for the official client. Because of this, it may change at any time. For long-term stability, it is better to Bring Your Own Key (BYOK) with a non-free model.
    • If you are writing a custom client, inject User-Agent: opencode/<version> into the request. Please also forward the user's real IP so per-IP quotas remain fair.
    • The solution i make is this simple proxy https://github.com/12errh/zen-proxy it just change the agent header line so it can work.

    Thanks. It seems that after that day, the 429 errors have become much less noticeable—maybe it was just a temporary service fluctuation on their end. Anyway, your analysis and the proxy solution are very helpful.

  5. 12errh commented on Aug 15, 2026

    @12errh

    @cubelitblade
    i get know another thing i am using mimo code. and priviously i set the contex window to 500k for deepseek v4 flash even everywhere it say the contex limit 200k. but now if the contex limit is grow from 200k then it start giving me 429 error . so i set the contex limit to 200k and see i make about 250 request and i do not get the 429 error.

    Image
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions