openclaw - 💡(How to fix) Fix OpenAI requests sent without Authorization header — wizard-saved openai:default (type: api_key) profile is ignored at request time

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

After completing the QuickStart Docker onboarding with OpenAI as the model provider, every OpenAI Responses API call from the embedded agent fails with HTTP 401 — and the OpenAI error message confirms no Authorization header was sent at all ("Missing bearer or basic authentication in header"). The key itself is valid (verified independently with curl). The wizard correctly persists the key to ~/.openclaw/agents/main/agent/auth-profiles.json, but the embedded agent's HTTP client never includes it on requests to https://api.openai.com/v1/responses.

This makes a fresh QuickStart Docker install of OpenClaw with OpenAI completely unusable end-to-end — the agent boots, channels connect, but every model call 401s.

Error Message

After completing the QuickStart Docker onboarding with OpenAI as the model provider, every OpenAI Responses API call from the embedded agent fails with HTTP 401 — and the OpenAI error message confirms no Authorization header was sent at all ("Missing bearer or basic authentication in header"). The key itself is valid (verified independently with curl). The wizard correctly persists the key to ~/.openclaw/agents/main/agent/auth-profiles.json, but the embedded agent's HTTP client never includes it on requests to https://api.openai.com/v1/responses. throw new Error(No API key resolved for provider "${provider}"...); Embedded agent's first OpenAI Responses API call uses the openai:default profile's key from auth-profiles.json and succeeds (or fails with a real OpenAI auth error if the key is bad). No more "Missing bearer" 401s when a valid api_key profile exists.

Root Cause

After completing the QuickStart Docker onboarding with OpenAI as the model provider, every OpenAI Responses API call from the embedded agent fails with HTTP 401 — and the OpenAI error message confirms no Authorization header was sent at all ("Missing bearer or basic authentication in header"). The key itself is valid (verified independently with curl). The wizard correctly persists the key to ~/.openclaw/agents/main/agent/auth-profiles.json, but the embedded agent's HTTP client never includes it on requests to https://api.openai.com/v1/responses.

This makes a fresh QuickStart Docker install of OpenClaw with OpenAI completely unusable end-to-end — the agent boots, channels connect, but every model call 401s.

Fix Action

Fix / Workaround

OpenAI's "Missing bearer or basic authentication in header" specifically means the request arrived without an Authorization header at all — not with a wrong/expired token. So the OpenAI provider runtime is dispatching the HTTP request without ever attaching the saved profile's key.

4. Workarounds attempted, all failed

Happy to test patches against this exact reproduction.

Code Example

auth or provider access failed for openai. Run /auth openai to refresh credentials...

---

{
  "version": 1,
  "profiles": {
    "openai:default": {
      "type": "api_key",
      "provider": "openai",
      "key": "sk-proj-...REDACTED-164-chars..."
    }
  }
}

---

"auth": {
  "profiles": {
    "openai:default": { "provider": "openai", "mode": "api_key" }
  }
}

---

$ curl -sS -o /dev/null -w "HTTP %{http_code}\n" https://api.openai.com/v1/models \
    -H "Authorization: Bearer sk-proj-..."
HTTP 200

---

{
  "subsystem": "model-fallback/decision",
  "event": "model_fallback_decision",
  "decision": "candidate_failed",
  "requestedProvider": "openai",
  "requestedModel": "gpt-5.5",
  "candidateProvider": "openai",
  "candidateModel": "gpt-5.5",
  "reason": "auth",
  "status": 401,
  "errorPreview": "unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: 9f87f891ab72ecbc-WAW"
}

---

{
  "event": "embedded_run_failover_decision",
  "stage": "prompt",
  "decision": "surface_error",
  "failoverReason": "auth",
  "profileFailureReason": "auth",
  "provider": "openai",
  "model": "gpt-5.5",
  "fallbackConfigured": false,
  "rawErrorPreview": "unexpected status 401 Unauthorized: Missing bearer or basic authentication in header"
}

---

export function requireApiKey(auth: ResolvedProviderAuth, provider: string): string {
  const key = normalizeSecretInput(auth.apiKey);
  if (key) return key;
  throw new Error(`No API key resolved for provider "${provider}"...`);
}
RAW_BUFFERClick to expand / collapse

OpenAI requests sent without Authorization header — wizard-saved openai:default (type: api_key) profile is ignored at request time

Summary

After completing the QuickStart Docker onboarding with OpenAI as the model provider, every OpenAI Responses API call from the embedded agent fails with HTTP 401 — and the OpenAI error message confirms no Authorization header was sent at all ("Missing bearer or basic authentication in header"). The key itself is valid (verified independently with curl). The wizard correctly persists the key to ~/.openclaw/agents/main/agent/auth-profiles.json, but the embedded agent's HTTP client never includes it on requests to https://api.openai.com/v1/responses.

This makes a fresh QuickStart Docker install of OpenClaw with OpenAI completely unusable end-to-end — the agent boots, channels connect, but every model call 401s.

Environment

  • OpenClaw built from main at commit 7ebcce6a3d68d0e24b147c995c008d836466fadb ("test: clarify qmd manager assertions"), banner version 2026.5.6
  • macOS 14 (Darwin 25.4.0), Apple Silicon
  • Docker Desktop, Compose v2
  • Install path: git clone https://github.com/openclaw/openclaw.git && ./scripts/docker/setup.sh (the documented Containerized gateway flow)

Reproduced twice on two clean clones, with ~/.openclaw and the openclaw:local image fully wiped between runs.

Reproduction

  1. Wipe any prior state: rm -rf ~/.openclaw && docker rmi openclaw:local.

  2. git clone https://github.com/openclaw/openclaw.git && cd openclaw && ./scripts/docker/setup.sh.

  3. Wizard: agree to the security disclaimer → QuickStartOpenAI → paste a known-valid sk-proj-... key → keep openai/gpt-5.5Telegram (Bot API) + bot token → skip web search → Configure skills now? YesSkip dependencies, answer No to all skill API-key prompts (Google Places, Notion, Whisper, ElevenLabs) → Skip hooksHatch in Terminal.

  4. The TUI boots. First model request fails immediately:

    auth or provider access failed for openai. Run /auth openai to refresh credentials...

Evidence

1. Key was saved correctly

~/.openclaw/agents/main/agent/auth-profiles.json:

{
  "version": 1,
  "profiles": {
    "openai:default": {
      "type": "api_key",
      "provider": "openai",
      "key": "sk-proj-...REDACTED-164-chars..."
    }
  }
}

The key is 164 ASCII characters, no masking artifact, no Unicode (verified key.isascii() == True).

~/.openclaw/openclaw.json carries only the shape of the profile, not the key:

"auth": {
  "profiles": {
    "openai:default": { "provider": "openai", "mode": "api_key" }
  }
}

2. Key is valid against OpenAI

Independent verification with curl:

$ curl -sS -o /dev/null -w "HTTP %{http_code}\n" https://api.openai.com/v1/models \
    -H "Authorization: Bearer sk-proj-..."
HTTP 200

3. OpenClaw sends no Authorization header

Gateway log entry from /tmp/openclaw/openclaw-2026-05-08.log inside the container (formatted; key fields preserved):

{
  "subsystem": "model-fallback/decision",
  "event": "model_fallback_decision",
  "decision": "candidate_failed",
  "requestedProvider": "openai",
  "requestedModel": "gpt-5.5",
  "candidateProvider": "openai",
  "candidateModel": "gpt-5.5",
  "reason": "auth",
  "status": 401,
  "errorPreview": "unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: 9f87f891ab72ecbc-WAW"
}

And from agent/embedded:

{
  "event": "embedded_run_failover_decision",
  "stage": "prompt",
  "decision": "surface_error",
  "failoverReason": "auth",
  "profileFailureReason": "auth",
  "provider": "openai",
  "model": "gpt-5.5",
  "fallbackConfigured": false,
  "rawErrorPreview": "unexpected status 401 Unauthorized: Missing bearer or basic authentication in header"
}

OpenAI's "Missing bearer or basic authentication in header" specifically means the request arrived without an Authorization header at all — not with a wrong/expired token. So the OpenAI provider runtime is dispatching the HTTP request without ever attaching the saved profile's key.

4. Workarounds attempted, all failed

All run after the initial 401 was observed:

  • openclaw models auth add — adds a second profile openai:manual of type: token with the same valid key. Saved to auth-profiles.json correctly. Still 401, still "Missing bearer".
  • openclaw models auth order set --provider openai openai:manual — order override applied (visible in ~/.openclaw/agents/main/agent/auth-state.json). Still 401.
  • docker compose restart openclaw-gateway — gateway reloads cleanly (log: config change requires gateway restart (auth.profiles.openai:manual, auth.order) then "ready"). Still 401.

5. Suspected code area

src/agents/model-auth-runtime-shared.ts defines:

export function requireApiKey(auth: ResolvedProviderAuth, provider: string): string {
  const key = normalizeSecretInput(auth.apiKey);
  if (key) return key;
  throw new Error(`No API key resolved for provider "${provider}"...`);
}

This requireApiKey should throw if it ever sees an empty key — but instead the request reaches OpenAI without a header, suggesting the OpenAI provider runtime is either bypassing requireApiKey entirely, or constructing the request with Authorization: Bearer ${undefined} (which fetch may strip), or reading the auth profile from a stale config snapshot that has only { provider, mode } from openclaw.json but not the key from auth-profiles.json.

The mtime of auth-profiles.json is included in the models-config fingerprint (src/agents/models-config.ts:59) so the file is known to the system — but its contents may not be threaded through to the actual provider HTTP client at request time.

Expected behavior

Embedded agent's first OpenAI Responses API call uses the openai:default profile's key from auth-profiles.json and succeeds (or fails with a real OpenAI auth error if the key is bad). No more "Missing bearer" 401s when a valid api_key profile exists.

Possible related work

The Unreleased changelog has:

Auth profiles: normalize inline API keys and tokens loaded from auth-profiles.json so masked or rich-text credential artifacts fail as auth errors instead of crashing HTTP header construction. Fixes #77624.

That fix targets masked keys (containing ). My key is clean ASCII, so #77624 is adjacent but not identical. There may be a deeper "where do we read the inline key from" gap that #77624's normalization does not cover.

What I can provide on request

  • Full unredacted ~/.openclaw/openclaw.json (auth section only — already shown above).
  • Full structured log lines (JSON) from /tmp/openclaw/openclaw-2026-05-08.log for the failing run.
  • A tcpdump/mitmproxy trace of the outbound OpenAI request showing the exact headers sent (have not run yet, can if needed).

Happy to test patches against this exact reproduction.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Embedded agent's first OpenAI Responses API call uses the openai:default profile's key from auth-profiles.json and succeeds (or fails with a real OpenAI auth error if the key is bad). No more "Missing bearer" 401s when a valid api_key profile exists.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix OpenAI requests sent without Authorization header — wizard-saved openai:default (type: api_key) profile is ignored at request time