April 15, 2026 • Versión: 2026.4.10

Ollama LLM no respeta el timeoutSeconds configurado

OpenClaw ignora la configuración de timeoutSeconds definida por el usuario y recurre a un timeout codificado de 15 segundos al esperar respuestas de Ollama, causando failover prematuro en modelos lentos basados en CPU.

🔍 Síntomas

Manifestación Principal

El agente recurre a un modelo de reserva a pesar de tener un timeout de 500 segundos configurado, con el timeout real disparándose después de 15 segundos:

openclaw-gateway-1  | 2026-04-12T22:02:44.589+00:00 [agent] embedded run timeout: runId=slug-gen-1776031345185 sessionId=slug-generator-1776031345185 timeoutMs=15000

Configuración Aplicada

El usuario aplicó la siguiente estructura de configuración (como se recomienda en la discusión de la comunidad):

{
  "agents": {
    "defaults": {
      "timeoutSeconds": 500,
      "llm": {
        "idleTimeoutSeconds": 500
      }
    }
  }
}

Tiempo de Calentamiento del Modelo

El modelo Ollama tarda más de 2 minutos solo en calentarse, lo cual es esperado para inferencia basada en CPU:

$ time docker compose exec ollama ollama run qwen2.5:7b "warmup"
Sure! What kind of warm-up would you like?

real    2m32.193s
user    0m0.059s
sys     0m0.027s

Secuencia de Failover

La secuencia completa de falla en los logs:

ollama-1 | [GIN] 2026/04/12 - 22:02:45 | 500 | 16.171687684s | 127.0.0.1 | POST "/api/chat"
openclaw-gateway-1 | [agent] embedded run timeout: timeoutMs=15000
openclaw-gateway-1 | [agent] embedded run failover decision: decision=fallback_model reason=timeout
openclaw-gateway-1 | [diagnostic] lane task error: error="FailoverError: LLM request timed out."

🧠 Causa Raíz

Desajuste de Ruta de Configuración

La configuración del usuario utiliza la estructura de ruta anidada incorrecta. La ruta agents.defaults.llm no existe en el esquema de configuración de OpenClaw para configuraciones de timeout. El valor de timeout se ignora silenciosamente y OpenClaw recurre a su valor predeterminado codificado de 15 segundos (15000ms).

Comportamiento del Timeout Hardcodeado

El runtime del agente de OpenClaw tiene un timeout predeterminado integrado que no se puede anular a través del bloque de configuración agents.defaults. Las rutas de configuración relevantes son:

  • agents.defaults.timeoutSeconds — Controla el timeout general del run del agente, no el timeout de la solicitud LLM
  • llm.requestTimeoutSeconds — La ruta correcta para el timeout de solicitud HTTP del LLM (no agents.defaults.llm)
  • llm.idleTimeoutSeconds — Controla el timeout de conexión inactiva, separado del timeout de solicitud

Fallo de Resolución de Configuración

Cuando OpenClaw analiza la configuración, valida las rutas contra el esquema. Las rutas desconocidas o no registradas se registran en nivel debug pero no causan fallos de inicio. El valor de timeout especificado en agents.defaults.timeoutSeconds se aplica a la capa de orquestación del agente, no al timeout del cliente HTTP del LLM subyacente.

Inmersión Técnica

El proveedor LLM (Ollama) usa un cliente HTTP con sus propios ajustes de timeout. En el código base de OpenClaw, el timeout de solicitud se pasa a través de opciones del proveedor:

// Representación de pseudocódigo del flujo de timeout
llmClient := NewLLMClient(llm.Config{
    RequestTimeout: config.GetInt("llm.requestTimeoutSeconds") * 1000, // valor por defecto 15000ms
})

// El timeout del orquestador de agentes (agents.defaults.timeoutSeconds) es separado
agentRunner := NewAgentRunner(AgentConfig{
    RunTimeout: config.GetInt("agents.defaults.timeoutSeconds") * 1000,
})

El proveedor Ollama se inicializa con el requestTimeout de llm.requestTimeoutSeconds, no de agents.defaults.timeoutSeconds.

🛠️ Solución Paso a Paso

Paso 1: Identificar la Ubicación del Archivo de Configuración

Localiza el archivo de configuración activo de OpenClaw:

# Para despliegues Docker Compose
docker compose config 2>/dev/null | grep -A5 "config:\|configFile:\|--config" || echo "Checking volumes..."

# Alternativa: Encontrar archivo de config en el contenedor
docker compose exec openclaw-gateway find / -name "*.yaml" -o -name "*.json" 2>/dev/null | grep -v proc

Paso 2: Actualizar la Configuración con las Rutas Correctas

Reemplaza la configuración existente con la estructura corregida:

Antes (Incorrecto):

{
  "agents": {
    "defaults": {
      "timeoutSeconds": 500,
      "llm": {
        "idleTimeoutSeconds": 500
      }
    }
  }
}

Después (Correcto):

{
  "agents": {
    "defaults": {
      "timeoutSeconds": 500
    }
  },
  "llm": {
    "requestTimeoutSeconds": 300,
    "idleTimeoutSeconds": 300
  },
  "providers": {
    "ollama": {
      "options": {
        "requestTimeoutSeconds": 300
      }
    }
  }
}

Paso 3: Para Override Específico del Proveedor (Recomendado)

Dado que estás usando Ollama, aplica el timeout directamente a la configuración del proveedor:

{
  "providers": {
    "ollama": {
      "options": {
        "requestTimeoutSeconds": 300
      }
    }
  }
}

Paso 4: Reiniciar los Servicios

docker compose down
docker compose up -d
docker compose logs -f openclaw-gateway 2>&1 | head -50

Paso 5: Verificar la Carga de Configuración

# Verificar advertencias de configuración al iniciar
docker compose logs openclaw-gateway 2>&1 | grep -i "warn\|config\|timeout"

Verificar que la config está cargada (buscar mensajes de validación)

docker compose exec openclaw-gateway cat /etc/openclaw/config.yaml 2>/dev/null ||
docker compose exec openclaw-gateway env | grep -i openclaw

🧪 Verificación

Método 1: Verificar los Logs de Inicio para el Valor de Timeout

# Iniciar limpio y capturar el arranque
docker compose down
docker compose up -d
sleep 5
docker compose logs openclaw-gateway 2>&1 | grep -iE "timeout|llm|request"

La salida esperada debe mostrar el valor de timeout configurado siendo cargado:

openclaw-gateway-1 | [init] LLM request timeout configured: 300s provider=ollama
openclaw-gateway-1 | [init] Configuration loaded successfully

Método 2: Ejecutar una Solicitud de Prueba y Medir

# Enviar una solicitud de prueba al gateway de OpenClaw
curl -X POST http://localhost:3000/api/v1/agent/run \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "default",
    "input": "Hello, respond with just the word OK",
    "model": "ollama/qwen2.5:7b"
  }' 2>&1 | tee /tmp/ollama_test.log &

Monitorizar el timeout real aplicado

watch -n 1 ‘docker compose logs –since 30s openclaw-gateway 2>&1 | grep -i timeout’

Método 3: Confirmar que el Tiempo de Respuesta de Ollama Excede el Timeout Anterior

# Prueba directa de Ollama (debería tomar 2+ minutos para calentamiento)
time docker compose exec ollama ollama run qwen2.5:7b "Say hello"

Esperado: Debe completarse sin error de timeout de OpenClaw

Comportamiento anterior: Falla después de 15 segundos con “LLM request timed out”

Comportamiento corregido: Espera la respuesta de Ollama hasta el timeout configurado

Método 4: Verificar vía Endpoint de Diagnóstico (si está disponible)

curl http://localhost:3000/api/v1/diagnostics 2>/dev/null | jq '.providers[] | select(.provider=="ollama") | .timeoutSeconds'

Salida esperada: 300

⚠️ Errores Comunes

1. Sensibilidad a Mayúsculas en la Ruta de Configuración

Las claves de configuración de OpenClaw distinguen mayúsculas de minúsculas. Estos no son equivalentes:

# INCORRECTO
"RequestTimeoutSeconds": 300

# CORRECTO
"requestTimeoutSeconds": 300

2. Suposiciones Incorrectas sobre Rutas Anidadas

No asumas que anidar configuraciones de timeout bajo agents.defaults.llm se propagará al proveedor LLM. El esquema de configuración usa espacios de nombres planos:

# INCORRECTO - Esta ruta no existe
agents.defaults.llm.requestTimeoutSeconds

# CORRECTO - Sección llm de nivel superior
llm.requestTimeoutSeconds

# TAMBIÉN CORRECTO - Opciones específicas del proveedor
providers.ollama.options.requestTimeoutSeconds

3. Desajuste de Unidades de Tiempo

Diferentes campos de configuración usan diferentes unidades:

  • timeoutSeconds — segundos (entero)
  • requestTimeoutSeconds — segundos (entero)
  • idleTimeoutSeconds — segundos (entero)
  • timeoutMs — milisegundos (como se ve en los logs)

Conversión: 300 segundos = 300,000 milisegundos

4. Caché de Volúmenes Docker

Los archivos de configuración montados a través de volúmenes pueden estar en caché. Forzar una recarga limpia:

docker compose down --remove-orphans
docker compose rm -f openclaw-gateway
docker compose up -d
# NO solo reiniciar; realizar拆卸 completa

5. Sobreescritura por Variable de Entorno

Las variables de entorno tienen precedencia sobre los archivos de configuración. Verificar configuraciones en conflicto:

docker compose config 2>/dev/null | grep -iE "timeout|env|OPENCLAW"
docker compose exec openclaw-gateway env | grep -iE "TIMEOUT|OLLAMA"

6. Específico de macOS: Limitación de CPU

En macOS con Apple Silicon, la emulación CPU de Ollama causa lentitud extrema. La primera respuesta puede tomar 5+ minutos incluso para consultas simples. Asegúrate de haber configurado un timeout que exceda tu latencia en el peor caso.

7. Carga del Modelo Ollama

El tiempo de carga inicial del modelo (como se ve en los logs: "llama runner started in 11.87 seconds") cuenta contra el timeout del LLM. Para modelos basados en CPU, agregar tiempo de buffer para dar cuenta de los arranques en frío.

🔗 Errores Relacionados

  • FailoverError: LLM request timed out — Error principal visto cuando el proveedor LLM excede el timeout configurado
  • embedded run timeout: timeoutMs=15000 — Mensaje de log indicando que se usó el valor predeterminado hardcodeado de 15 segundos
  • embedded run failover decision: fallback_model — Decisión tomada debido al disparador de timeout
  • Issue #46049 — Problema relacionado de configuración de timeout con proveedores LLM externos
  • Issue #24235 — Inconsistencia histórica en el manejo de timeout en OpenClaw
  • HTTP 500 from Ollama — Ollama retornando error de servidor después de respuesta lenta; a menudo mal interpretado como timeout
  • strconv.ParseInt: parsing "max" — Advertencia de parsing de cuota CPU en el contenedor Ollama (inofensiva, no relacionada con timeout)

Matriz de Solución de Problemas

SíntomaCausa RaízSolución
Timeout a los 15s a pesar de la configRuta de config incorrectaUsar providers.{provider}.options.requestTimeoutSeconds
Timeout a los 30s a pesar de config de 300sSobreescritura por variable de entornoVerificar variable env OPENCLAW_LLM_TIMEOUT
Timeout exactamente después de 60sTimeout de load balancer/proxyVerificar configuración de nginx/docker proxy
Ollama retorna 500 después de 15sTimeout upstream + error de OllamaAumentar tanto los timeout de Ollama como de OpenClaw

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.