1. Symptoms
The clw-auth-invalid error in OpenClaw manifests during API initialization or authentication handshakes, typically when calling clw_init() or clw_authenticate(). This error indicates that the provided credentials or token are rejected by the OpenClaw authentication server.
Common symptoms include:
clw_auth_invalid: Authentication failed. Invalid or malformed token provided.
Or in verbose logging:
[ERROR] clw_client.c:147: clw_http_request() failed with HTTP 401 Unauthorized
[ERROR] Response body: {"error": "clw-auth-invalid", "message": "Token signature invalid or expired"}
Applications may crash, hang, or fallback to offline mode. On Linux/macOS, you might see this in dmesg or journalctl if OpenClaw is linked to system services:
openclaw[12345]: clw-auth-invalid at clw_auth_verify_token()
In Windows Event Viewer, look for Application logs under OpenClaw source:
Event ID 1001: clw-auth-invalid - Access denied due to invalid auth.
Network traces (e.g., via tcpdump or Wireshark) reveal HTTPS requests to auth.openclaw.io:443 returning 401 with JSON payload as above. CPU usage spikes briefly during retry loops, and subsequent calls to clw_query() or clw_submit() fail similarly.
This error blocks all authenticated endpoints, rendering features like cloud saves, leaderboards, or multiplayer matchmaking unusable.
2. Root Cause
OpenClaw uses JWT-based token authentication signed with RS256 (RSA-256). The clw-auth-invalid error triggers when:
- Invalid Token Structure: Token is malformed (e.g., missing segments, incorrect base64 padding).
- Expired or Revoked Token:
expclaim past current time, or token blacklisted server-side. - Signature Mismatch: Client secret/key mismatch, or token tampered.
- Clock Skew: Client system time drifts >5 minutes from server NTP-synced time.
- Configuration Errors: Wrong
client_id,client_secret, or environment (dev/prod mismatch). - Network/Proxy Interference: Proxies stripping auth headers or modifying TLS.
Internally, OpenClaw’s clw_auth_verify_token() parses the JWT header/payload/signature, validates against public keys fetched from https://auth.openclaw.io/.well-known/jwks.json, and checks claims like iss (issuer), aud (audience), sub (subject).
Example failing JWT payload (decoded):
{
"iss": "https://auth.openclaw.io",
"aud": "openclaw-client",
"exp": 1729000000, // Past timestamp
"iat": 1728990000,
"sub": "user-123"
}
Server rejects if signature fails openssl dgst -sha256 -verify equivalent. Rate-limiting (429 after 5 fails/min) can compound into auth loops.
3. Step-by-Step Fix
Follow these steps to resolve clw-auth-invalid. Test incrementally.
Step 1: Verify System Clock
Sync time with NTP:
Before (causing skew):
# No sync, clock drifts
date # Shows incorrect time, e.g., 2024-10-17 instead of 2024-10-18
After:
# Linux/macOS
sudo ntpdate -s pool.ntp.org
# Or systemd-timesyncd: sudo timedatectl set-ntp true
# Windows
w32tm /resync
# Verify
date # Matches server time within 30s
Step 2: Inspect Current Configuration
Dump OpenClaw config:
#include <openclaw.h>
#include <stdio.h>
int main() {
clw_config_t *cfg = clw_config_load("~/.openclaw/config.json");
if (!cfg) {
fprintf(stderr, "Failed to load config\n");
return 1;
}
printf("Client ID: %s\n", cfg->client_id);
printf("Token: %.*s...\n", 20, cfg->token);
clw_config_free(cfg);
return 0;
}
Compile: gcc -o dump-config dump-config.c -lopenclaw
Step 3: Regenerate Token
Use OpenClaw CLI or dashboard.
Before (invalid token in code):
// Broken: Hardcoded expired token
clw_config_t cfg = {
.client_id = "my-app-123",
.client_secret = "expired_secret_xyz",
.token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.invalid_signature_here"
};
clw_error_t err = clw_init(&cfg);
if (err == CLW_AUTH_INVALID) {
fprintf(stderr, "clw-auth-invalid\n"); // Triggers error
}
After (fresh token):
// Fixed: Fetch via clw_token_acquire()
#include <openclaw.h>
clw_config_t cfg = {
.client_id = "my-app-123",
.client_secret = "valid_secret_abc123", // From dashboard
.endpoint = "https://auth.openclaw.io" // Ensure prod/dev match
};
clw_error_t err = clw_token_acquire(&cfg); // Exchanges client_id/secret for JWT
if (err != CLW_SUCCESS) {
fprintf(stderr, "Token acquire failed: %d\n", err);
return 1;
}
err = clw_init(&cfg);
if (err == CLW_SUCCESS) {
printf("Authenticated successfully\n");
}
clw_shutdown();
Generate token CLI:
clw-token-gen --client-id my-app-123 --secret valid_secret_abc123 --output ~/.openclaw/token.jwt
Step 4: Secure Config with Environment Variables
Avoid hardcoding:
Before:
// ~/.openclaw/config.json - Exposed
{
"client_id": "my-app-123",
"client_secret": "valid_secret_abc123"
}
After:
// Use env vars
cfg.client_id = getenv("CLAW_CLIENT_ID");
cfg.client_secret = getenv("CLAW_CLIENT_SECRET");
Set env:
export CLAW_CLIENT_ID=my-app-123
export CLAW_CLIENT_SECRET=valid_secret_abc123
Step 5: Handle Retries and Fallbacks
Implement exponential backoff:
int retries = 0;
while (retries < 3) {
err = clw_init(&cfg);
if (err == CLW_AUTH_INVALID) {
clw_token_refresh(&cfg);
sleep(pow(2, retries)); // 1s, 2s, 4s
retries++;
} else {
break;
}
}
4. Verification
Re-run your app:
./my-openclaw-app [INFO] clw_init() succeeded. Token valid until 2024-10-19T12:00:00ZTest API call:
clw_query_result_t *res = clw_query("leaderboard/top10"); if (res->status == 200) { printf("Verified: %s\n", res->data); } clw_query_free(res);Validate token manually:
# Install jwt-cli: cargo install jwt-cli jwt decode ~/.openclaw/token.jwt --key-fetch https://auth.openclaw.io/.well-known/jwks.json # Should show valid claims without errorsNetwork check:
curl -H "Authorization: Bearer $(cat ~/.openclaw/token.jwt)" https://api.openclaw.io/ping -v # Expect 200 OK
Monitor logs for 10 minutes under load. Success: No clw-auth-invalid occurrences.
5. Common Pitfalls
- Token Caching: Reusing old tokens across app restarts without refresh. Fix: Call
clw_token_refresh()onCLW_TOKEN_EXPIRED. - Environment Mismatch: Dev tokens (
dev.auth.openclaw.io) invalid on prod. Checkcfg.endpoint. - Proxy Stripping Headers: Corporate proxies remove
Authorization. SetCLAW_PROXY=http://proxy:8080. - Key Rotation: OpenClaw rotates JWKS weekly. Force
clw_jwks_fetch()if signature fails. - Base64 Padding: Manual token construction forgets
=. Always useclw_token_acquire(). - Permissions:
client_secretscoped wrong (e.g., read-only for write ops). Regenerate with full scopes. - IPv6 Issues: Auth server IPv6 glitches. Force IPv4:
cfg.ipv6 = false;.
Pitfall log example:
[WARNING] JWKS fetch failed: clw-network-timeout -> cascades to clw-auth-invalid
⚠️ Unverified: Docker clock skew if host/container desynced—use --privileged cautiously.
6. Related Errors
| Error Code | Description | Differentiation |
|---|---|---|
clw-auth-missing | No token provided | Check cfg.token != NULL vs. invalid content |
clw-network-timeout | Auth server unreachable | Precedes auth-invalid on retries |
clw-invalid-request | Malformed query post-auth | Succeeds init(), fails endpoint |
clw-token-expired | Valid sig but past exp | Auto-refreshable unlike invalid |
Cross-reference clw-auth-missing guide for token absence.
(Word count: 1256. Code blocks: ~42%)