April 20, 2026

[429 Ratenlimit betrifft gesamten Google-Anbieter statt spezifisches Modell] - Google Gemini Provider: 429 Rate Limit Scopes to Entire Provider Instead of Specific Model

Wenn ein einzelnes Google Gemini-Modell das Ratenlimit (429) erreicht, wendet das OpenClaw-Gateway ein Backoff auf den gesamten 'google'-Anbieter an und blockiert so den Zugriff auf andere, unabhÀngige Modelle mit eigenen Kontingenten.

🔍 Symptome

Hauptmanifestation

Wenn ein bestimmtes Google Gemini-Modell sein Kontingent erschöpft hat, schlagen alle nachfolgenden Anfragen an jedes Modell unter dem google-Anbieter mit Ratenlimit-Fehlern fehl, selbst wenn diese Modelle unabhÀngige Kontingentzuweisungen haben.

Fehlerausgabe-Beispiele

Direkte API-Antwort (429 von Google):

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": {
    "code": 429,
    "message": "Resource has been exhausted (e.g. check quota).",
    "status": "RESOURCE_EXHAUSTED"
  }
}

OpenClaw Gateway-Antwort nach Backoff-Aktivierung:

{
  "error": {
    "type": "rate_limit_exceeded",
    "provider": "google",
    "message": "Provider 'google' is currently in cooldown due to rate limiting. Retry-After: 120s",
    "retry_after": 120
  }
}

Verhaltenssymptome

  • Keine Modellisolierung: Der Wechsel von gemini-3.1-pro-preview-customtools zu gemini-3.0-pro-preview stellt die FunktionalitĂ€t nicht wieder her.
  • Erweiterte NichtverfĂŒgbarkeit: Alle google-Anbieter-Anfragen schlagen fehl, bis der Anbieter-Ebene-Cooldown ablĂ€uft.
  • Kein Fallback-Pfad: Alternative Modelle unter demselben Anbieter können wĂ€hrend von Ratenlimit-Ereignissen nicht als Fallbacks dienen.
  • Gateway-Ebene-Ablehnung: Anfragen können auf der OpenClaw-Gateway-Ebene abgelehnt werden, bevor sie Googles API erreichen.

Reproduktionsszenario

# Step 1: Request to rate-limited model
curl -X POST https://api.openclaw.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.1-pro-preview-customtools", "messages": [{"role": "user", "content": "test"}]}'
# Response: 429 from Google API

# Step 2: Immediate fallback to another model
curl -X POST https://api.openclaw.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.0-pro-preview", "messages": [{"role": "user", "content": "test"}]}'
# Expected: Request proceeds to Google API
# Actual: 429 or backoff error from OpenClaw gateway

🧠 Ursache

Architekturanalyse

Die Ursache liegt in der anbieterbasierten Ratenlimit-Verfolgung-Implementierung innerhalb des Retry/Backoff-Mechanismus des OpenClaw-Gateways.

Fehlersequenz

  1. Anfrage an gemini-3.1-pro-preview-customtools: Die modellspezifische Bereitstellung erhÀlt ein 429 RESOURCE_EXHAUSTED von Googles API.
  2. Gateway fÀngt 429 ab: OpenClaws Fehlerbehandlungs-Middleware fÀngt die 429-Antwort ab.
  3. Anbieter-Ebene-Backoff-Aktivierung: Anstatt das Ratenlimit gegen das spezifische Modell/die Bereitstellung zu erfassen, setzt das Gateway einen Cooldown-Timer auf den google-Anbieterbezeichner.
  4. Nachfolgende Anfrage an gemini-3.0-pro-preview: Das Gateway prĂŒft, ob der google-Anbieter im Cooldown ist. Da dies der Fall ist, lehnt es die Anfrage vorab mit einem Backoff-Fehler ab.
  5. Modell mit unabhÀngigem Kontingent wird blockiert: gemini-3.0-pro-preview hat möglicherweise eine völlig separate Kontingentzuweisung, kann aber nicht zugegriffen werden.

Code-Ebene Ursache

Die Ratenlimit-Verfolgung verwendet wahrscheinlich eine Datenstruktur Àhnlich zu:

// Simplified representation of current behavior
const providerBackoff = {
  "google": {
    cooldownUntil: 1699999999999,  // Unix timestamp
    reason: "rate_limit",
    retryAfter: 120
  }
};

// Backoff check
function shouldReject(provider) {
  return providerBackoff[provider]?.cooldownUntil > Date.now();
}

Das Problem: Der Backoff wird nach Anbieternamen (“google”) statt nach Modell- oder Bereitstellungsbezeichner verschlĂŒsselt.

Google Gemini API Kontingentarchitektur

Google Gemini API arbeitet mit:

  • Modellspezifischen Kontingenten: Jedes Modell (z.B. gemini-3.1-pro-preview-customtools) hat unabhĂ€ngige Ratenlimits.
  • Projektbezogenen Kontingenten: Breitere Limits, die alle Modelle betreffen, aber diese sind typischerweise viel höher.
  • Regionalen Endpunkten: Können unabhĂ€ngige Limits haben.

Abweichende Codepfade

SzenarioAktuelles VerhaltenErwartetes Verhalten
Modell A trifft 429Gesamter google-Anbieter blockiertNur Modell A blockiert
Modell A Kontingent erschöpftModell B unbrauchbarModell B fĂ€hrt fort, wenn Kontingent verfĂŒgbar
Anbieter-Backoff aktivGateway lehnt auf Schicht 7 abAnfrage erreicht API

đŸ› ïž Schritt-fĂŒr-Schritt-Lösung

Option 1: Modellbezogene Ratenlimitierung aktivieren (Empfohlen)

Wenn OpenClaw die modellbezogene Ratenlimit-Verfolgung unterstĂŒtzt, konfigurieren Sie das Gateway fĂŒr modellbezogenen Backoff:

Vorher (openclaw.yaml):

providers:
  google:
    api_key: "${GOOGLE_API_KEY}"
    rate_limit:
      strategy: "provider"  # Current: blocks entire provider
      retry_after: 120

Nachher:

providers:
  google:
    api_key: "${GOOGLE_API_KEY}"
    rate_limit:
      strategy: "model"  # Changed: per-model tracking
      retry_after: 120
      scope: "deployment"  # Granularity: model/deployment level

Option 2: Modellspezifische Fallbacks konfigurieren

Definieren Sie explizite Fallback-Ketten, um ratenlimitierte Modelle zu umgehen:

Vorher:

models:
  - name: "gemini-3.1-pro-preview-customtools"
    provider: "google"

Nachher:

models:
  - name: "gemini-3.1-pro-preview-customtools"
    provider: "google"
    fallback_models:
      - "gemini-3.0-pro-preview"
      - "gemini-pro"

  - name: "gemini-3.0-pro-preview"
    provider: "google"
    fallback_models:
      - "gemini-pro"

Option 3: Erhöhung der Anbieter-Cooldown-GranularitÀt (Code-Fix)

Wenn Sie Zugriff auf den OpenClaw-Quellcode haben, Àndern Sie die Ratenlimit-Verfolgung:

Schritt 1: Ratenlimit-Handler identifizieren

Locate the file handling 429 responses. Typically found at:

src/gateway/middleware/rate-limit-handler.ts
src/providers/google/error-handler.ts

Schritt 2: Backoff-SchlĂŒssel von Anbieter auf Modell Ă€ndern

// BEFORE (provider-level)
providerBackoff[provider] = {
  cooldownUntil: Date.now() + retryAfter * 1000,
  reason: "rate_limit"
};

// AFTER (model-level)
const modelKey = `${provider}:${model}`;
modelBackoff[modelKey] = {
  cooldownUntil: Date.now() + retryAfter * 1000,
  reason: "rate_limit",
  model: model,
  provider: provider
};

Schritt 3: Die AblehnungsprĂŒfung aktualisieren

// BEFORE
function shouldReject(request) {
  const provider = request.provider;
  return providerBackoff[provider]?.cooldownUntil > Date.now();
}

// AFTER
function shouldReject(request) {
  const modelKey = `${request.provider}:${request.model}`;
  const providerKey = request.provider;
  
  // Check model-specific backoff first
  if (modelBackoff[modelKey]?.cooldownUntil > Date.now()) {
    return { rejected: true, reason: "model_rate_limited" };
  }
  
  // Fallback to provider-level for shared limits only
  if (providerBackoff[providerKey]?.cooldownUntil > Date.now()) {
    return { rejected: true, reason: "provider_rate_limited" };
  }
  
  return { rejected: false };
}

Option 4: Workaround ĂŒber mehrere Anbieterinstanzen

Erstellen Sie separate Anbieterkonfigurationen fĂŒr Modelle mit unabhĂ€ngigen Kontingenten:

providers:
  google-gemini-31:
    api_key: "${GOOGLE_API_KEY}"
    models:
      - "gemini-3.1-pro-preview-customtools"
    rate_limit:
      retry_after: 60

  google-gemini-30:
    api_key: "${GOOGLE_API_KEY}"
    models:
      - "gemini-3.0-pro-preview"
    rate_limit:
      retry_after: 60

  google-gemini-pro:
    api_key: "${GOOGLE_API_KEY}"
    models:
      - "gemini-pro"
    rate_limit:
      retry_after: 60

đŸ§Ș Verifizierung

Test 1: Modellbezogene Isolierung nach dem Fix bestÀtigen

# Step 1: Trigger rate limit on model A
curl -X POST https://api.openclaw.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.1-pro-preview-customtools", "messages": [{"role": "user", "content": "test"}]}'

# Expected: 429 from Google API
# Verify with: echo $? (should be non-zero)

# Step 2: Immediately test model B access
curl -X POST https://api.openclaw.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.0-pro-preview", "messages": [{"role": "user", "content": "test"}]}'

# Expected: 200 OK or valid API response (not gateway backoff error)

Test 2: Modellspezifischen Backoff-Zustand verifizieren

PrĂŒfen Sie den internen Zustand des Gateways (falls ĂŒber Admin-Endpunkt verfĂŒgbar):

GET /admin/rate-limit-status

# Expected response structure:
{
  "providers": {
    "google": {
      "cooldown": false,
      "models": {
        "gemini-3.1-pro-preview-customtools": {
          "cooldown": true,
          "retry_after": 120,
          "expires_at": "2024-01-15T10:30:00Z"
        },
        "gemini-3.0-pro-preview": {
          "cooldown": false
        }
      }
    }
  }
}

Test 3: Gleichzeitiger ModellverfĂŒgbarkeitstest

# Run concurrent requests to different models
for model in "gemini-3.1-pro-preview-customtools" "gemini-3.0-pro-preview" "gemini-pro"; do
  echo "Testing: $model"
  curl -s -o /dev/null -w "%{http_code}\n" \
    -X POST https://api.openclaw.io/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"$model\", \"messages\": [{\"role\": \"user\", \"content\": \"test\"}]}"
done

# Expected: 
# gemini-3.1-pro-preview-customtools: 429 (rate limited)
# gemini-3.0-pro-preview: 200 (independent quota)
# gemini-pro: 200 (independent quota)

Test 4: Backoff-Ablauf-Verifizierung

# Wait for cooldown to expire
echo "Waiting for model cooldown expiration..."
sleep 130  # retry_after + buffer

# Verify previously rate-limited model is accessible
curl -X POST https://api.openclaw.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.1-pro-preview-customtools", "messages": [{"role": "user", "content": "test"}]}'

# Expected: 200 OK

Erfolgskriterien

  • ✅ Nach Ratenlimit auf gemini-3.1-pro-preview-customtools bleiben andere google-Modelle erreichbar.
  • ✅ Der modellspezifische Backoff-Zustand wird korrekt verfolgt und lĂ€uft unabhĂ€ngig ab.
  • ✅ Das Gateway lehnt Anfragen an nicht ratenlimitierte Modelle nicht vorab ab.
  • ✅ Fallback-Ketten funktionieren korrekt, wenn das primĂ€re Modell nicht verfĂŒgbar ist.

⚠ HĂ€ufige Fehler

Umgebungsspezifische Fallen

Docker-Container-Caching

# Pitfall: Container filesystem may cache rate limit state
# Restarting containers may not reset state if persistence is enabled

docker-compose down
docker volume prune openclaw-cache  # Clear cached state
docker-compose up -d

Kubernetes-Volume-Mounts

Falls persistente Volumes fĂŒr Ratenlimit-Verfolgung verwendet werden:

# Verify PVC is not stale after config changes
kubectl get pvc | grep openclaw
kubectl describe pvc openclaw-cache

# May need to delete and recreate if schema changed
kubectl delete pvc openclaw-cache
# Then restart deployments

macOS-Entwicklungsumgebung

# Pitfall: Local rate limit state may persist across terminal sessions
# Clear any local state files
rm -rf ~/.openclaw/cache/*
rm -rf .openclaw/state.json

Konfigurationsfehler

Falscher Anbietername in der Fallback-Kette

# WRONG: Typos in provider name cause silent failures
models:
  - name: "gemini-3.0-pro-preview"
    provider: "googel"  # Typo - will not match actual provider

# CORRECT:
models:
  - name: "gemini-3.0-pro-preview"
    provider: "google"

Überlappende Modelldeklarationen

# WRONG: Same model declared multiple times
models:
  - name: "gemini-3.0-pro-preview"
    provider: "google"
  - name: "gemini-3.0-pro-preview"  # Duplicate
    provider: "google"
    fallback_models: [...]

API-SchlĂŒssel-Umfang-Mismatch

# Pitfall: Google API keys may have different quotas per project
# If using separate provider instances, ensure they use keys with adequate quotas

# Verify in Google Cloud Console:
# APIs & Services > Enabled APIs > Vertex AI API > Quotas

Testen von GrenzfÀllen

Ratenlimit auf dem letzten verfĂŒgbaren Modell

# Scenario: All models under a provider are rate-limited
# Expected: Should return clear error, not silent success

# Verify error response includes all affected models
curl -X POST https://api.openclaw.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.0-pro-preview", "messages": [{"role": "user", "content": "test"}]}'

# Check response contains actionable information
# Should NOT be empty 200 OK

Schneller Modellwechsel

# Pitfall: Race condition during rapid switching may bypass backoff
# Test with concurrent requests

ab -n 100 -c 10 -T 'application/json' \
  -p request.json \
  https://api.openclaw.io/v1/chat/completions

# Verify all requests are properly rate-limited or processed

🔗 Zugehörige Fehler

FehlercodeBeschreibungVerbindung
429 RESOURCE_EXHAUSTEDGoogle API gab Ratenlimit-Fehler zurĂŒckQuellfehler, der Anbieter-Backoff auslöst
503 Service UnavailableAnbieter vorĂŒbergehend nicht verfĂŒgbarNachgelagert bei verlĂ€ngertem Anbieter-Backoff
500 Internal Server ErrorGateway-Fehler wÀhrend Backoff-HandlingUnbehandelte Ausnahme in der Ratenlimit-Middleware
ENOTFOUNDDNS-Auflösung fehlgeschlagen fĂŒr Google APIUnabhĂ€ngig, kann aber als Ratenlimit fehldiagnostiziert werden
ETIMEDOUTVerbindungs-Timeout zu Google APIUnabhÀngig, kann aber falsche Backoff-Logik auslösen
INVALID_ARGUMENTFehlerhafte Anfrage an Gemini APIKann in der Fehlerbehandlung als Ratenlimit fehlgeleitet werden

Historischer Kontext

Dieses Problem bezieht sich auf breitere Muster im Design von Multi-Tenant-API-Gateways:

  • ÜbermĂ€ĂŸig breite Circuit Breaker: Circuit-Breaker-Muster werden auf Anbieterebene angewendet, obwohl sie auf Modell-/Bereitstellungsebene arbeiten sollten.
  • Kollision gemeinsam genutzter ZustĂ€nde: Mehrere unabhĂ€ngige Ressourcen teilen sich einen einzigen Ratenlimit-ZĂ€hler.
  • Unzureichender Fehlerkontext: 429-Antworten von Google enthalten retryInfo, das angibt, welches Kontingent erschöpft ist, aber dies wird möglicherweise nicht geparst.

Zugehörige GitHub-Issues

Belege & Quellen

Diese Troubleshooting-Anleitung wurde automatisch von der FixClaw Intelligence Pipeline aus Community-Diskussionen synthetisiert.