Skip to content

auth.json not loaded automatically in new sessions — provider Authorization header missing #36181

Open

Description

@diegofer039-cloud

Description

After configuring providers via /connect (which stores API keys in ~/.local/share/opencode/auth.json), opening a new session of opencode in a new terminal window fails to send the Authorization header when calling the provider API.

For example, with NVIDIA provider configured properly in both opencode.json (models) and auth.json (API key nvapi-...), using /model in a new session returns:

Unauthorized: Header of type `authorization` was missing

Running /connect again in the same session and re-entering the same key fixes it immediately — proving the key in auth.json is correct but was not loaded by opencode on startup.

Steps to reproduce

  1. Configure NVIDIA provider via /connect, which stores the key in auth.json
  2. Verify auth.json contains a valid entry: {"nvidia": {"type": "api", "key": "nvapi-..."}}
  3. Verify opencode.json has the provider and models configured:
    "nvidia": {
      "models": {
        "deepseek-ai/deepseek-v4-pro": {
          "name": "DeepSeek V4 Pro"
        }
      }
    }
  4. Close terminal, open a new terminal
  5. Run opencode and use /model to select the NVIDIA model
  6. Actual result: Provider returns Unauthorized: Header of type authorization was missing
  7. Run /connect, select NVIDIA, re-enter the same key
  8. Use /model again
  9. Expected result: Works correctly

Workaround

Running /connect manually every session and re-entering the API key works, but defeats the purpose of persistent auth storage in auth.json.

Environment

  • OpenCode version: [please specify]
  • OS: Windows 11
  • Terminal: Windows Terminal / PowerShell

Related issues

Activity

  1. hui6900 commented on Aug 5, 2026

    @hui6900

    [SUPERSEDED] — See this comment for the verified conclusion (direct SSH testing): the 401 in our environment is serve's own HTTP Basic Auth gate (client lacked OPENCODE_SERVER_PASSWORD), and auth.json was intact and its key valid. The "auth.json not loaded" framing below is retracted; the auth.json path claims were also corrected in this comment.


    Adding a data point from our deployment: this issue also affects opencode serve (headless server mode) after a process restart, not only new TUI sessions.

    Environment

    • Ubuntu 22.04 (headless server), opencode serve running as a systemd user service, listening on port 4096
    • Binary version: 1.18.13_F050429 (custom fork build)
    • Restart time: 2026-08-05 16:13 CST

    Symptoms

    • After restarting the opencode serve process, every LLM request returns 401 Unauthorized — the provider credentials in auth.json are not loaded by the new process.
    • auth.json exists at both candidate paths and holds the expected provider entries (no corruption observed):
      • /root/.local/share/opencode/auth.json
      • /root/.config/opencode/auth.json
    • In serve mode there is no interactive /connect to re-authenticate, so the 401 state persists until the process is externally stopped/reconfigured.

    This looks like the same "auth.json not loaded on startup" root cause as described here, manifesting in serve mode instead of a new TUI session. The concurrent-write race referenced in #30396 also seems plausible as a root cause for a restart scenario. Happy to run a debug build or capture startup logs if that helps narrow it down.

  2. hui6900 commented on Aug 5, 2026

    @hui6900

    Correction to my previous comment (facts verified on the server, 2026-08-05):

    Some details in my earlier comment were not accurate. Verified facts below:

    • auth.json: only /root/.local/share/opencode/auth.json exists (202 bytes, JSON is valid, contains two provider entries: deepseek, moonshotai-cn). /root/.config/opencode/auth.json does not exist — my earlier "exists at both candidate paths" was wrong.
    • Service start time: systemd reports ExecMainStartTimestamp = 2026-08-05 16:57:22 CST for the running opencode.service (MainPID 369912). I could not verify a restart at 16:13 CST.
    • Current 401 reproduction (via direct localhost curl, bypassing the machine's outbound proxy): GET http://127.0.0.1:4096/v1/models → 401 with empty body; also 401 when sending Authorization: Bearer <OPENCODE_SERVER_PASSWORD> and x-opencode-token. I cannot yet tell whether this 401 comes from serve's own password gate or from provider auth not being loaded — the auth header format for the serve API is not confirmed.
    • Binary: 1.18.13_F050429 at /root/.opencode/bin/opencode (note: F050429 looks like a custom build marker).

    I'll update this comment if I can pin down whether the 401 is caused by auth.json not being loaded (the root cause this issue is about) versus serve's own auth gate.

  3. hui6900 commented on Aug 5, 2026

    @hui6900

    Final verification result (direct SSH test on the server, 2026-08-05, per my earlier "I'll update this comment"):

    The 401 we hit is serve's own HTTP Basic Auth gate, not an auth.json loading problem.

    Layer-by-layer curl results (all against the running opencode serve on port 4096):

    Request Result
    GET /v1/models (no auth) 401
    GET /v1/models with Authorization: Basic base64(opencode:<OPENCODE_SERVER_PASSWORD>) 200
    GET / with same Basic auth 200
    GET /app with same Basic auth 200
    GET https://api.deepseek.com/models with the API key from auth.json (Bearer) 200

    auth.json (/root/.local/share/opencode/auth.json, the only path opencode reads — it uses Global.Path.data/auth.json) is intact (providers: deepseek, moonshotai-cn) and the stored key is valid against the provider API. opencode serve authenticates correctly once the client sends the Basic credentials.

    So in our environment the observed 401 is the password gate rejecting an unauthenticated client — not a case of "auth.json not loaded on startup" as this issue describes. The earlier guesses in my first comment (and the plausible-cause framing) should be disregarded. If a client starts getting 401 after a serve restart, the more likely cause is that the client process does not have OPENCODE_SERVER_PASSWORD set/matching the server's (the password inside a systemd unit is not automatically passed on to client processes), not that auth.json was dropped.

  4. oe3gwu commented on Sep 19, 2026

    @oe3gwu

    same. but i added .local/share/opencode/auth.json and .config/opencode/opencode.json manually. They are 100% correct, but the model defined in opencode.json doesnt find its corresponding API Key. On V1 it works like a charm.

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