#Groq API key valid in curl but OpenClaw returns HTTP 401 on every agent run

1 messages · Page 1 of 1 (latest)

violet ibex
#

OpenClaw 2026.4.26 on Ubuntu 22.04 VPS.

Telegram bot connects, but EVERY agent run fails with
"HTTP 401: Invalid API Key" on Groq.

But same key works directly:
curl https://api.groq.com/openai/v1/models -H "Authorization: Bearer $KEY"
Returns 200 OK with models list.

Config has correct key (length 56, no whitespace).

Tried (no fix):

  • openclaw config set models.providers.groq (multiple times)
  • systemctl restart openclaw
  • rm -rf sessions, cache, /tmp/openclaw, auth-profiles
  • npm install -g openclaw@latest --force
  • openclaw doctor
  • Generated fresh keys multiple times

Also seeing in logs:

  • amazon-bedrock-mantle plugin: Cannot find module './user-profiles.js'
  • google plugin: Cannot find module './auth/googleauth'
  • Gateway warning: missing scope: operator.read

Same 401 error happens with Groq, Mistral, Google -
all configured with valid keys verified by curl.

Help appreciated! 🙏

peak lotusBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

humble saddleBOT
#

This smells less like a bad Groq key and more like OpenClaw is resolving a different credential/agent — plus those plugin Cannot find module... errors suggest install/runtime corruption.

Please paste these outputs, with secrets redacted:

which openclaw
openclaw --version
openclaw gateway status --deep
openclaw config get meta.lastTouchedVersion
openclaw agents list --bindings

openclaw models status --probe --probe-provider groq
openclaw infer model run --model groq/llama-3.1-8b-instant --prompt "reply exactly: pong" --json

If Telegram is bound to a non-main agent, also run:

#
openclaw models status --agent <agentId> --probe --probe-provider groq

Key things:

  • daemon/systemd must see GROQ_API_KEY; shell-only env vars won’t count. (docs.openclaw.ai)
  • auth profiles are per-agent, so Telegram may be using a different agent store. (docs.openclaw.ai)
  • missing scope: operator.read is degraded diagnostics, not the model 401. (docs.openclaw.ai)
  • models status --probe is the right next check for live auth resolution. (docs.openclaw.ai)
violet ibex
humble saddleBOT
#

Ahh yep, that would do it. Nice catch 🎯

OpenClaw env precedence is “existing process env wins,” so an old GROQ_API_KEY can shadow the valid key in models.json / config.

After restart, I’d verify with:

openclaw models status --probe --probe-provider groq
openclaw infer model run --model groq/llama-3.1-8b-instant --prompt "reply exactly: pong" --json

If that passes, the root cause is solved. If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it for future users.

violet ibex
# humble saddle Ahh yep, that would do it. Nice catch 🎯 OpenClaw env precedence is “existing p...

SOLVED partially!

Removed conflicting GROQ_API_KEY env var from:

  • ~/.bashrc
  • /etc/systemd/system/openclaw.service
  • ~/.config/systemd/user/openclaw-gateway.service

Now models.json key is being used:

  • Auth probe: groq/llama-3.3-70b-versatile = ok ✅

But Telegram bot still showing 401 error.
Investigating if Telegram uses different agent store.

Plugin errors persist:

  • amazon-bedrock-mantle: Cannot find module './user-profiles.js'
  • google: Cannot find module './auth/googleauth'

Tried plugins reinstall + plugin-runtime-deps clear.
Errors return after each reinstall.

humble saddleBOT
#

Nice, that’s real progress.

For the remaining Telegram 401, I’d check these in order:

openclaw agents list --bindings

Find the agent Telegram is bound to, then:

openclaw models status --agent <agentId> --probe --probe-provider groq

Also try clearing the Telegram session state with /new or /reset in the Telegram chat, in case it’s pinned to an old model/auth override.

For the plugin errors: treat those as a separate install/runtime-deps issue unless they’re blocking Telegram. If they keep returning after doctor --fix, please file a GitHub issue with openclaw --version, openclaw status --all, and the plugin error log lines:

violet ibex
# humble saddle Nice, that’s real progress. For the remaining Telegram 401, I’d check these in ...

Update: Removed conflicting GROQ_API_KEY env var.
Auth probe now shows: groq/llama-3.3-70b-versatile = ok ✅

But Telegram bot still 401. Also have port conflict
between system openclaw.service and user
openclaw-gateway.service.

Plugin errors persist after multiple reinstalls:

  • amazon-bedrock-mantle: Cannot find module './user-profiles.js'
  • google: Cannot find module './auth/googleauth'

How do I cleanly run a single gateway?
Should I disable system service and only use user service,
or vice versa?

humble saddleBOT
#

Use one gateway only. On Ubuntu VPS I’d recommend the user service unless you intentionally built a system-wide/root-managed install.

Clean path:

# Stop/disable system-level duplicates
sudo systemctl disable --now openclaw.service 2>/dev/null || true
sudo systemctl disable --now openclaw-gateway.service 2>/dev/null || true
sudo systemctl daemon-reload

# Install/refresh the user service
openclaw gateway install --force
systemctl --user enable --now openclaw-gateway.service

# Keep user service alive after logout
sudo loginctl enable-linger "$USER"
#

# Verify only one gateway remains
openclaw gateway status --deep
openclaw status --all

Then retest Telegram. The 401 is very likely coming from the other still-running gateway using the old env/config.

If you prefer the system service instead, that’s fine too — but then disable/remove the user service and treat the system unit as externally managed. Don’t run both on the same port/profile.

violet ibex
humble saddleBOT
#

Perfect — that should eliminate the split-brain piece.

After the Telegram test, the useful sanity checks are:

openclaw models status --probe --probe-provider groq
openclaw channels status --probe
openclaw logs --follow

If Telegram still 401s while the Groq probe is OK, check which agent Telegram is routed to:

openclaw agents list --bindings
openclaw models status --agent <telegramAgentId> --probe --probe-provider groq
#

You’re on the right track now.

violet ibex
humble saddleBOT
#

Yep — don’t delete more state yet. At this point we need to split CLI auth vs running gateway auth vs Telegram agent run.

Run both:

openclaw infer model run --local --model groq/llama-3.3-70b-versatile --prompt "reply exactly: pong" --json
openclaw infer model run --gateway --model groq/llama-3.3-70b-versatile --prompt "reply exactly: pong" --json

If --local passes but --gateway fails, the user service still has different env/config than your shell.

If both pass but Telegram fails, then paste the openclaw logs --follow lines from exactly when Telegram /new fails. Please include the provider/model line if shown, but redact tokens/keys.

Useful docs for this exact distinction: https://docs.openclaw.ai/cli/infer

violet ibex
# humble saddle Yep — don’t delete more state yet. At this point we need to split **CLI auth** v...

URGENT: Different auth resolution for probe vs runtime!

openclaw models status --probe --probe-provider groq
→ Status: ok ✅ (uses models.json key gsk_9GsS...)

But Telegram agent run STILL returns 401:
"runId":"8c8d545d...","provider":"groq",
"model":"llama-3.3-70b-versatile",
"profileFailureReason":"auth",
"errorPreview":"401 Invalid API Key"

Single gateway, single agent (main), no env var conflict.
Auth probe says key works. Runtime says 401.

Same model, same agent, same auth profile -
why does probe succeed but runtime fail?

This looks like a runtime credential resolution bug
where the agent runtime path uses different/cached
credentials than the probe path.

Logs available if needed.

humble saddleBOT
#

Yes — that pattern strongly suggests probe is testing the models.json credential, but the embedded agent runtime is selecting a different credential path, likely a stale groq:* auth profile.

Fast workaround: force Groq to use the explicit API-key provider config and skip profile selection:

openclaw config set models.providers.groq.auth '"api-key"' --strict-json
openclaw gateway restart

openclaw infer model run --gateway --model groq/llama-3.3-70b-versatile --prompt "reply exactly: pong" --json

Then test Telegram again.

Also check whether stale Groq profiles exist — don’t paste secrets:

#
jq -r '.profiles | to_entries[] | select(.value.provider=="groq") | "\(.key)\t\(.value.type)"' \
  ~/.openclaw/agents/main/agent/auth-profiles.json

Important distinction: models status --probe can prove one available credential source works; it doesn’t necessarily prove the full agent runtime selected that same source. The runtime error’s profileFailureReason:"auth" points right at auth-profile/runtime selection.

Config key reference: https://docs.openclaw.ai/gateway/config-tools

violet ibex
# humble saddle ```bash jq -r '.profiles | to_entries[] | select(.value.provider=="groq") | "\(....

HUGE PROGRESS!

Local works (auth ok), only hitting Groq rate limit:
"413 Request too large for model llama-3.3-70b-versatile"
"Limit 12000, Requested 17227"

Gateway still 401:
"GatewayClientRequestError: FailoverError: HTTP 401"

So local agent runtime resolves credentials correctly,
but gateway runtime path uses stale profile.

Removed all stale Groq profiles from auth-profiles.json.
Switching default to llama-3.1-8b-instant for smaller context.

Will test gateway after restart!

Token issue suggests skills/persona files inflate
the system prompt significantly. Any way to limit
context for Telegram channel specifically?

humble saddleBOT
#

Huge progress indeed 🎉

For Telegram-specific context, the cleanest answer is: use a separate Telegram agent. Channel-level config can pin a model, but prompt/context budgets are mostly agent-scoped, not channel-scoped.

Best pattern:

openclaw agents add tg-lite --workspace ~/.openclaw/workspace-tg-lite --bind telegram:default --non-interactive

Then in config for that agent, keep it lean:

{
  agents: {
    list: [
#
      {
        id: "tg-lite",
        model: "groq/...",
        skills: [],
        bootstrapTotalMaxChars: 8000,
        bootstrapMaxChars: 3000,
        skillsLimits: { maxSkillsPromptChars: 2000 },
        contextInjection: "continuation-skip"
      }
    ]
  }
}

For Telegram group history specifically, you can also reduce supplemental chat context:

#
openclaw config set channels.telegram.historyLimit 0

But that only reduces Telegram history context — it won’t shrink AGENTS.md / SOUL.md / skills. For that, the separate lean agent is the right fix.

After removing stale Groq profiles, definitely retest:

openclaw gateway restart
openclaw infer model run --gateway --model groq/llama-3.1-8b-instant --prompt "reply exactly: pong" --json

If gateway passes, Telegram should finally stop 401ing.

violet ibex
# humble saddle Huge progress indeed 🎉 For **Telegram-specific context**, the cleanest answer ...

Genius solution! 🙏

Yes, my main agent has 30+ skills loaded which inflates
context to ~17k tokens (Groq TPM limit is 12k).

Creating separate tg-lite agent now with:

  • No skills
  • bootstrapTotalMaxChars: 8000
  • maxSkillsPromptChars: 2000
  • contextInjection: continuation-skip

Plus historyLimit: 0 for Telegram channel.

Will keep main agent for CLI/web use with all skills,
and tg-lite specifically for Telegram with lean context.

Testing gateway run with llama-3.1-8b-instant first,
then Telegram. Will confirm shortly!

humble saddleBOT
#

Nice, that split is exactly what I’d do.

One small correction to watch for: skillsLimits.maxSkillsPromptChars is the per-agent key, so the shape should be:

{
  id: "tg-lite",
  skills: [],
  bootstrapTotalMaxChars: 8000,
  bootstrapMaxChars: 3000,
  skillsLimits: {
    maxSkillsPromptChars: 2000
  },
  contextInjection: "continuation-skip"
}
#

After config changes:

openclaw gateway restart
openclaw agents list --bindings
openclaw models status --agent tg-lite --probe --probe-provider groq

And if it works, please mark the solution — this thread is going to be really useful for future “curl works but runtime 401s” cases.

violet ibex
# humble saddle Nice, that split is exactly what I’d do. One small correction to watch for: `sk...

🎉 SOLVED! Telegram bot is working!

Final solution chain:

  1. Removed conflicting GROQ_API_KEY env var
  2. Set models.providers.groq.auth = "api-key"
  3. Created tg-lite lean agent
  4. Switched to OpenAI gpt-4o-mini (Groq free tier
    too restrictive for my 30+ skill setup)
  5. Temporarily disabled skills to clear cache
  6. Now restoring skills - OpenAI 128k context
    handles them fine

Bot replies in Bengali, full multi-skill capability:

  • SEO explanations ✅
  • Business idea generation ✅
  • User context retention ✅

Marking your message as solution!
Thank you for the systematic debugging -
specifically the auth='api-key' workaround
was the breakthrough! 🙏