April 20, 2026

[Error 429 de límite de tasa afecta todo el proveedor en lugar de un modelo específico] - Google Gemini Provider: 429 Rate Limit Scopes to Entire Provider Instead of Specific Model

Cuando un único modelo de Google Gemini alcanza el límite de tasa (429), la puerta de enlace OpenClaw aplica backoff a todo el proveedor 'google', bloqueando el acceso a otros modelos no relacionados con cuotas independientes.

🔍 Síntomas

Manifestación Principal

Cuando un modelo específico de Google Gemini agota su cuota, todas las solicitudes posteriores a cualquier modelo bajo el proveedor google fallan con errores de límite de tasa, incluso cuando esos modelos tienen asignaciones de cuota independientes.

Ejemplos de Salida de Error

Respuesta directa de API (429 de 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"
  }
}

Respuesta del gateway OpenClaw después de que se active el retroalimentación:

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

Síntomas de Comportamiento

  • Sin Aislamiento de Modelo: Cambiar de gemini-3.1-pro-preview-customtools a gemini-3.0-pro-preview no restaura la funcionalidad.
  • Indisponibilidad Extendida: Todas las solicitudes del proveedor google fallan hasta que expire el enfriamiento a nivel de proveedor.
  • Sin Ruta de Respaldo: Los modelos alternativos bajo el mismo proveedor no pueden servir como respaldo durante eventos de límite de tasa.
  • Rechazo a Nivel de Gateway: Las solicitudes pueden ser rechazadas en la capa del gateway OpenClaw antes de llegar a la API de Google.

Escenario de Reproducción

# Paso 1: Solicitud al modelo con límite de tasa
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"}]}'
# Respuesta: 429 de Google API

# Paso 2: Respaldo inmediato a otro modelo
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"}]}'
# Esperado: La solicitud procede a Google API
# Actual: 429 o error de retroalimentación del gateway OpenClaw

🧠 Causa Raíz

Análisis de Arquitectura

La causa raíz reside en la implementación del seguimiento de límite de tasa a nivel de proveedor dentro del mecanismo de reintento/retroalimentación del gateway OpenClaw.

Secuencia de Falla

  1. Solicitud a gemini-3.1-pro-preview-customtools: El despliegue específico del modelo recibe un 429 RESOURCE_EXHAUSTED de la API de Google.
  2. Gateway Intercepta 429: El middleware de manejo de errores de OpenClaw captura la respuesta 429.
  3. Activación de Retroalimentación a Nivel de Proveedor: En lugar de registrar el límite de tasa contra el modelo/despliegue específico, el gateway establece un temporizador de enfriamiento en el identificador del proveedor google.
  4. Solicitud Subsecuente a gemini-3.0-pro-preview: El gateway verifica si el proveedor google está en enfriamiento. Al encontrar que lo está, rechaza la solicitud preventivamente con un error de retroalimentación.
  5. Modelo con Cuota Independiente es Bloqueado: gemini-3.0-pro-preview puede tener una asignación de cuota completamente separada, pero no puede ser accedido.

Causa Raíz a Nivel de Código

El seguimiento de límite de tasa probablemente usa una estructura de datos similar a:

// Representación simplificada del comportamiento actual
const providerBackoff = {
  "google": {
    cooldownUntil: 1699999999999,  // Unix timestamp
    reason: "rate_limit",
    retryAfter: 120
  }
};

// Verificación de retroalimentación
function shouldReject(provider) {
  return providerBackoff[provider]?.cooldownUntil > Date.now();
}

El problema: El retroalimentación está identificado por el nombre del proveedor (“google”) en lugar del identificador del modelo o despliegue.

Arquitectura de Cuota de Google Gemini API

Google Gemini API opera con:

  • Cuotas específicas por modelo: Cada modelo (ej. gemini-3.1-pro-preview-customtools) tiene límites de tasa independientes.
  • Cuotas a nivel de proyecto: Límites más amplios que afectan a todos los modelos, pero típicamente son mucho más altos.
  • Endpoints regionales: Pueden tener límites independientes.

Rutas de Código Divergentes

EscenarioComportamiento ActualComportamiento Esperado
Modelo A recibe 429Todo el proveedor google bloqueadoSolo Modelo A bloqueado
Cuota de Modelo A agotadaModelo B inutilizableModelo B continúa si hay cuota disponible
Retroalimentación de proveedor activoGateway rechaza en capa 7Solicitud procede a API

🛠️ Solución Paso a Paso

Opción 1: Habilitar Limitación de Tasa por Modelo (Recomendado)

Si OpenClaw soporta seguimiento de límite de tasa por modelo, configura el gateway para usar retroalimentación a nivel de modelo:

Antes (openclaw.yaml):

providers:
  google:
    api_key: "${GOOGLE_API_KEY}"
    rate_limit:
      strategy: "provider"  # Actual: bloquea todo el proveedor
      retry_after: 120

Después:

providers:
  google:
    api_key: "${GOOGLE_API_KEY}"
    rate_limit:
      strategy: "model"  # Cambiado: seguimiento por modelo
      retry_after: 120
      scope: "deployment"  # Granularidad: nivel de modelo/despliegue

Opción 2: Configurar Respaldos Específicos por Modelo

Define cadenas de respaldo explícitas para evitar modelos con límite de tasa:

Antes:

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

Después:

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"

Opción 3: Aumentar Granularidad del Enfriamiento del Proveedor (Corrección de Código)

Si tienes acceso al código fuente de OpenClaw, modifica el seguimiento de límite de tasa:

Paso 1: Identificar el manejador de límite de tasa

Localiza el archivo que maneja respuestas 429. Típicamente encontrado en:

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

Paso 2: Modificar la clave de retroalimentación de proveedor a modelo

// ANTES (a nivel de proveedor)
providerBackoff[provider] = {
  cooldownUntil: Date.now() + retryAfter * 1000,
  reason: "rate_limit"
};

// DESPUÉS (a nivel de modelo)
const modelKey = `${provider}:${model}`;
modelBackoff[modelKey] = {
  cooldownUntil: Date.now() + retryAfter * 1000,
  reason: "rate_limit",
  model: model,
  provider: provider
};

Paso 3: Actualizar la verificación de rechazo

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

// DESPUÉS
function shouldReject(request) {
  const modelKey = `${request.provider}:${request.model}`;
  const providerKey = request.provider;
  
  // Verificar retroalimentación específica del modelo primero
  if (modelBackoff[modelKey]?.cooldownUntil > Date.now()) {
    return { rejected: true, reason: "model_rate_limited" };
  }
  
  // Respaldo a nivel de proveedor solo para límites compartidos
  if (providerBackoff[providerKey]?.cooldownUntil > Date.now()) {
    return { rejected: true, reason: "provider_rate_limited" };
  }
  
  return { rejected: false };
}

Opción 4: Solución Alternativa via Múltiples Instancias de Proveedor

Crea configuraciones de proveedor separadas para modelos con cuotas independientes:

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

🧪 Verificación

Prueba 1: Confirmar Aislamiento a Nivel de Modelo Después de la Corrección

# Paso 1: Activar límite de tasa en modelo 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"}]}'

# Esperado: 429 de Google API
# Verificar con: echo $? (debe ser distinto de cero)

# Paso 2: Probar inmediatamente acceso al modelo B
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"}]}'

# Esperado: 200 OK o respuesta válida de API (no error de retroalimentación del gateway)

Prueba 2: Verificar Estado de Retroalimentación Específico del Modelo

Verifica el estado interno del gateway (si se expone via endpoint de administración):

GET /admin/rate-limit-status

# Estructura de respuesta esperada:
{
  "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
        }
      }
    }
  }
}

Prueba 3: Prueba de Disponibilidad de Modelos Concurrentes

# Ejecutar solicitudes concurrentes a diferentes modelos
for model in "gemini-3.1-pro-preview-customtools" "gemini-3.0-pro-preview" "gemini-pro"; do
  echo "Probando: $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

# Esperado: 
# gemini-3.1-pro-preview-customtools: 429 (límite de tasa)
# gemini-3.0-pro-preview: 200 (cuota independiente)
# gemini-pro: 200 (cuota independiente)

Prueba 4: Verificación de Expiración del Retroalimentación

# Esperar a que expire el enfriamiento
echo "Esperando expiración del enfriamiento del modelo..."
sleep 130  # retry_after + buffer

# Verificar que el modelo previamente limitado esté accesible
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"}]}'

# Esperado: 200 OK

Criterios de Éxito

  • ✅ Después del límite de tasa en gemini-3.1-pro-preview-customtools, otros modelos google permanecen accesibles.
  • ✅ El estado de retroalimentación específico del modelo se rastrea correctamente y expira independientemente.
  • ✅ El gateway no rechaza preventivamente solicitudes a modelos sin límite de tasa.
  • ✅ Las cadenas de respaldo funcionan correctamente cuando el modelo primario no está disponible.

⚠️ Errores Comunes

Trampas Específicas del Entorno

Caché de Contenedores Docker

# Trampa: El sistema de archivos del contenedor puede caché el estado de límite de tasa
# Reiniciar contenedores puede no restablecer el estado si la persistencia está habilitada

docker-compose down
docker volume prune openclaw-cache  # Limpiar estado en caché
docker-compose up -d

Montajes de Volumen en Kubernetes

Si usas volúmenes persistentes para el seguimiento de límite de tasa:

# Verificar que el PVC no esté desactualizado después de cambios de configuración
kubectl get pvc | grep openclaw
kubectl describe pvc openclaw-cache

# Puede ser necesario eliminar y recrear si el esquema cambió
kubectl delete pvc openclaw-cache
# Luego reiniciar los despliegues

Entorno de Desarrollo macOS

# Trampa: El estado local de límite de tasa puede persistir entre sesiones de terminal
# Limpiar cualquier archivo de estado local
rm -rf ~/.openclaw/cache/*
rm -rf .openclaw/state.json

Errores de Configuración

Nombre Incorrecto de Proveedor en Cadena de Respaldo

# INCORRECTO: Errores tipográficos en el nombre del proveedor causan fallas silenciosas
models:
  - name: "gemini-3.0-pro-preview"
    provider: "googel"  # Error tipográfico - no coincidirá con el proveedor real

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

Declaraciones de Modelo Superpuestas

# INCORRECTO: Mismo modelo declarado múltiples veces
models:
  - name: "gemini-3.0-pro-preview"
    provider: "google"
  - name: "gemini-3.0-pro-preview"  # Duplicado
    provider: "google"
    fallback_models: [...]

Desajuste de Alcance de Clave API

# Trampa: Las claves API de Google pueden tener diferentes cuotas por proyecto
# Si usas instancias de proveedor separadas, asegúrate de que usen claves con cuotas adecuadas

# Verificar en Google Cloud Console:
# APIs & Services > Enabled APIs > Vertex AI API > Quotas

Casos de Prueba Extremos

Límite de Tasa en Último Modelo Disponible

# Escenario: Todos los modelos bajo un proveedor tienen límite de tasa
# Esperado: Debe devolver un error claro, no un éxito silencioso

# Verificar que la respuesta de error incluya todos los modelos afectados
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"}]}'

# Verificar que la respuesta contenga información accionable
# NO debe ser un 200 OK vacío

Cambio Rápido de Modelo

# Trampa: Condición de carrera durante cambio rápido puede evadir el retroalimentación
# Probar con solicitudes concurrentes

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

# Verificar que todas las solicitudes estén correctamente limitadas o procesadas

🔗 Errores Relacionados

Código de ErrorDescripciónConexión
429 RESOURCE_EXHAUSTEDLa API de Google devolvió error de límite de tasaError fuente que activa el retroalimentación del proveedor
503 Service UnavailableProveedor temporalmente no disponibleDerivado de retroalimentación de proveedor prolongado
500 Internal Server ErrorError del gateway durante manejo de retroalimentaciónExcepción no manejada en middleware de límite de tasa
ENOTFOUNDFallo de resolución DNS para API de GoogleSin relación pero puede ser mal diagnosticado como límite de tasa
ETIMEDOUTTiempo de conexión agotado a API de GoogleSin relación pero puede activar lógica de retroalimentación incorrecta
INVALID_ARGUMENTSolicitud mal formada a API de GeminiPuede ser mal enrutado como límite de tasa en manejo de errores

Contexto Histórico

Este problema se relaciona con patrones más amplios en el diseño de gateways de API multi-tenant:

  • Cortacircuitos Demasiado Amplios: Aplicar patrones de cortacircuitos a nivel de proveedor cuando deberían operar a nivel de modelo/despliegue.
  • Colisión de Estado Compartido: Múltiples recursos independientes compartiendo un único contador de límite de tasa.
  • Contexto de Error Insuficiente: Las respuestas 429 de Google incluyen retryInfo que especifica qué cuota fue agotada, pero esto puede no ser analizado.

Issues de GitHub Relacionados

Evidencia y fuentes

Esta guía de solución de problemas fue sintetizada automáticamente por la tubería de inteligencia de FixClaw a partir de las discusiones de la comunidad.