Solución de problemas
Empieza por la capa que falla: navegador, frontend, backend, Ollama, plugin de proveedor o red del despliegue.
Comprobaciones rápidas
# App branch and local changes
git status
# Backend process liveness
curl http://localhost:3001/health/live
# Backend dependency readiness (SQLite, schema, and writable data storage)
curl http://localhost:3001/health/ready
# Ollama health
curl http://localhost:11434/api/tags
# Installed Ollama models
ollama list
En desarrollo, el frontend suele estar en http://localhost:5173 y el backend en http://localhost:3001. El flujo empaquetado npx libre-webui sirve la aplicación en http://localhost:8080.
Libre WebUI no se inicia
Comprueba Node y las dependencias
node --version
npm install
npm run dev
Se requiere Node.js 22.22 o posterior.
Puerto en uso
lsof -i :3001
lsof -i :5173
lsof -i :8080
Detén el proceso anterior o configura otro puerto.
El backend no puede escribir datos
El backend almacena los datos en DATA_DIR si está definida, si no en backend/data. Los inicios desde fuente resuelven un DATA_DIR relativo desde el directorio del backend, no la shell. Por ello DATA_DIR=./data selecciona backend/data, mientras el valor histórico DATA_DIR=./backend/data selecciona backend/backend/data. Comprueba que se pueda escribir. Sin DATA_DIR, Libre conserva el directorio histórico si es el único almacén. Si ambos contienen datos, detén Libre, copia ambos y elige o migra deliberadamente; nunca combina ni copia bases divergentes.
Los endpoints distinguen un proceso vivo de una aplicación utilizable:
/healthy/health/livedevuelven200mientras el backend sirva HTTP. Los proveedores opcionales no afectan./health/readydevuelve503si una base, esquema, almacenamiento o dependencia obligatoria no está disponible. No espera a proveedores opcionales y su respuesta pública omite errores y detalles./health/deepejecuta comprobaciones de integridad y claves foráneas de SQLite en un trabajador acotado y agrupa sondeos opcionales como Ollama. Su caída es una advertencia, no vuelve no preparado lo obligatorio. Exige un Bearer de administrador actual y no sirve para sondeos frecuentes.
curl -H "Authorization: Bearer $LIBRE_ADMIN_TOKEN" \
http://localhost:3001/health/deep
El navegador no llega al backend
En desarrollo, el frontend usa VITE_API_BASE_URL si está definida y de lo contrario el backend predeterminado.
Ejemplo de .env del frontend:
VITE_API_BASE_URL=http://localhost:3001/api
VITE_WS_BASE_URL=ws://localhost:3001
VITE_WS_BASE_URL es opcional, pero al definirla es la base de los sockets de Chat y terminal Work. Usa una URL absoluta ws: o wss:; admite prefijos como wss://example.com/libre. No incluyas credenciales, consultas ni fragmentos. Reinicia o recompila tras cambiar variables Vite.
Ejemplo de .env del backend:
CORS_ORIGIN=http://localhost:5173,http://127.0.0.1:5173
Para teléfono, LAN o Tailscale, no apuntes el teléfono a localhost; utiliza la IP LAN o Tailscale del portátil y ejecuta el servidor enlazado al host:
npm run dev:host
Esto sirve el frontend en el puerto 8080 y reenvía el tráfico de API y
WebSocket al backend local en el puerto 3001. Solo el puerto 8080 necesita ser
accesible desde el otro dispositivo. Si VITE_API_BASE_URL o
VITE_WS_BASE_URL está definida en frontend/.env, asegúrate de que esas URL
sean accesibles desde el otro dispositivo, o elimínalas para usar el proxy del
servidor de desarrollo.
Chat no transmite tras un proxy inverso
El síntoma habitual es que se envían mensajes pero no aparece respuesta y la consola muestra un fallo WebSocket. Confirma que el proxy admita actualizaciones y no cierre conexiones largas.
Cuando se configura alguno, las actualizaciones del navegador con Origin se comprueban contra CORS_ORIGIN y BASE_URL. Define al menos uno para un despliegue remoto; sin ambos el filtro sigue permisivo para desarrollo. Electron y otros clientes pueden omitir Origin, pero deben canjear Authorization por un ticket breve de un uso. Mantén el backend tras TLS y los mismos controles que la API HTTP.
Para un host público, permite ese origen en el servicio:
services:
libre-webui:
environment:
CORS_ORIGIN: https://chat.example.com
BASE_URL: https://chat.example.com
Los ejemplos de nginx y Caddy suponen que el proxy está en el host Docker, donde Compose publica Libre WebUI en 8080. Si se une a la red Compose, usa libre-webui:3001 como upstream.
nginx
nginx requiere reenviar expresamente las cabeceras. La espera larga mantiene abierto un chat inactivo mientras trabaja el modelo.
location /ws {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
Recarga nginx tras validar con nginx -t.
Caddy
reverse_proxy de Caddy admite WebSockets directamente:
chat.example.com {
reverse_proxy 127.0.0.1:8080
}
Traefik
Traefik también gestiona las actualizaciones. Si su proveedor Docker comparte la red, bastan etiquetas normales:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.libre-webui.rule=Host(`chat.example.com`)'
- 'traefik.http.routers.libre-webui.entrypoints=websecure'
- 'traefik.http.routers.libre-webui.tls=true'
- 'traefik.http.services.libre-webui.loadbalancer.server.port=3001'
Si conecta y se corta, comprueba esperas de inactividad en proxies o equilibradores. Si Traefik impone el límite, ajusta transport.respondingTimeouts del punto de entrada.
Ollama no se detecta
Confirma que Ollama se ejecute
curl http://localhost:11434/api/tags
Configura una URL personalizada
.env del backend:
OLLAMA_BASE_URL=http://localhost:11434
Si Libre WebUI está en Docker y Ollama en el host, utiliza el archivo Compose externo o apunta OLLAMA_BASE_URL a una dirección del host accesible desde el contenedor.
Problemas al descargar modelos
Descarga primero desde el terminal
ollama pull gemma4:12b
Si falla, el problema está fuera de Libre WebUI.
Modelos en la nube
Usa el filtro de nube del gestor para Ollama Cloud. Libre WebUI normaliza los sufijos necesarios; no hace falta añadir :cloud manualmente a entradas compatibles.
Un usuario no puede descargar
Los administradores pueden impedir descargas a usuarios normales. Comprueba los ajustes si pueden navegar pero no instalar.
Chat es lento o falla
- Usa un modelo más pequeño.
- Comprueba los cargados con
ollama ps. - Reduce el contexto.
- Reduce los tokens máximos de respuestas largas.
- Confirma que cabe en RAM/VRAM.
- En plugins, verifica clave y cuota.
La generación de imágenes OpenAI no está disponible
- Activa el proveedor incluido. Guarda una clave para el usuario o configura la reserva de confianza
OPENAI_API_KEY. - Abre los ajustes de imágenes, actívalas y selecciona un modelo GPT Image anunciado.
- Prefiere
gpt-image-2. Los ID anteriores son solo para compatibilidad y están obsoletos. - Deja
image_endpointvacío salvo que operes uno compatible. Un endpoint/responseso/chat/completionsno procesa Image API. - Si OpenAI rechaza con clave y cuota válidas, confirma que la organización pueda usar GPT Image.
La disponibilidad se evalúa con la credencial del usuario o la reserva incluida. Una clave de otra cuenta no expone modelos.
Problemas de endpoints de proveedores
Si un proveedor compatible recibe solicitudes en una ruta incorrecta, revisa Ajustes → Plugins:
- Elige Chat Completions para
/chat/completionso Responses para/responses. - Introduce la raíz, como
https://provider.example/v1, como URL base. - Deja la ruta vacía para el valor del modo o introduce una ruta con barra inicial.
- Un endpoint completo verdaderamente personalizado prevalece; bórralo para volver a Base URL y API Path. Los valores que solo igualan el antiguo predeterminado se ignoran tras actualizar. Un sufijo
/chat/completionso/responsestambién determina el formato para impedir cargas erróneas.
El JSON importado admite formatos OpenAI Chat Completions, OpenAI Responses, Anthropic o Gemini. Un formato propietario de carga, streaming, herramientas o respuesta necesita un adaptador; cambiar solo el endpoint no lo traduce.
Las URL admiten HTTP o HTTPS. HTTP envía credenciales y tráfico sin cifrar, así que resérvalo para puertas autoalojadas fiables y prefiere HTTPS. Las URL base no pueden incluir consulta ni fragmento, y las rutas relativas no pueden contener traversal literal o recodificado, consultas ni fragmentos. Se rechaza codificación excesiva que no se estabilice.
La actualización sustituye sufijos conocidos, incluido /responses, por /models. Activación, actualización y anulaciones usan endpoint y clave del usuario. Guardar o borrar la clave y restablecer conexión también actualiza; los parámetros de generación no. Los ID se guardan por usuario y no reescriben JSON. Si la ruta derivada no funciona, configura model_map.
Las solicitudes no siguen redirecciones HTTP, incluido descubrimiento, Chat, Work, imágenes, embeddings y voz. Configura el destino final. Así Authorization no salta a un destino no validado.
Si Work indica que cambió el enrutamiento, inicia una ejecución nueva tras terminar el cambio. Se detiene antes de la siguiente solicitud para no repetir estado anterior a otro modo, endpoint o clave.
Las solicitudes salen del backend; localhost dentro de un contenedor es el contenedor, no el host. En Compose o Kubernetes utiliza DNS del servicio, como http://ai-gateway:8080/v1. Usa http://host.docker.internal:8080/v1 solo si existe. HTTP sigue sin cifrar.
Los modelos de imagen, anulaciones y claves también se resuelven para el usuario actual. Verifica la autenticación si parecen de otra cuenta.
También se aplican estas reglas:
- Inicia sesión como administrador para cambiar rutas. Definiciones y conexiones son configuración de instancia; los usuarios guardan generación, credenciales y activación.
- Con
endpointoapi_url, introduce la URL completa de operación, por ejemplohttps://provider.example/v1/chat/completions. Una raíz solo va enbase_url, junto aapi_modeyapi_pathopcional. - Se aceptan HTTP y HTTPS absolutas. Usa HTTP solo en red fiable porque claves, prompts y respuestas no están cifrados.
- Una anulación vacía usa el manifiesto. Una explícita no segura se rechaza; Libre no vuelve silenciosamente.
- Una clave de entorno solo se usa si una definición incluida no sombreada mantiene raíz, autenticación, endpoints y selectores y valores de enrutamiento de confianza. Las importadas, escribibles con ID incluido y rutas personalizadas exigen credencial de la misma cuenta. Libre informa no disponible y omite descubrimiento si solo hay clave de entorno.
- Las definiciones personalizadas antiguas están en cuarentena por falta de procedencia. Reimporta como administrador y haz que cada usuario reactive. Editar JSON directamente vuelve a ponerlo en cuarentena; usa instalación o actualización.
- Las credenciales guardadas se vinculan a la ruta, el contrato de autenticación, la definición y la fuente vigentes al introducirlas. Añadir o quitar modelos las conserva. Tras cambiar un endpoint o cualquier otra parte de la definición, vuelve a guardar la credencial de esa cuenta. Una credencial antigua sin vínculo solo migra automáticamente en una ruta incluida anclada exacta.
- Los plugins importados pueden usar
api_url;endpointprevalece. Si la lista está en otro lugar, definemodels_endpointcompleto; se valida y no redirige. - Activa tras guardar endpoint y credencial. La activación deriva
/modelsy usa la credencial del usuario salvomodels_endpoint. Guardar o restablecer también actualiza y espera antes de recargar. La activación es por cuenta. - En Ajustes → Plugins, usa Actualizar modelos. La tabla de lectura muestra ID configurados o descubiertos. Un fallo transitorio conserva el catálogo anterior o
model_map; terminar no demuestra que el remoto esté sano. - El descubrimiento automático exige matriz
data. Los catálogos son por usuario. Una activación normal conserva el anterior; cambiar conexión lo borra primero y un fallo usamodel_map. - La disponibilidad de imágenes y claves también es por usuario; verifica quién está autenticado.
- Si un usuario no administrador guardó enrutamiento antiguo, usa Restablecer. Se purga el valor ignorado y los modelos descubiertos para que no revivan tras cambiar rol.
- Las solicitudes se originan en el backend;
localhosten contenedor es el contenedor. - No se siguen redirecciones; configura la URL final.
Chat usa el proveedor equivocado o lo muestra no disponible
El mismo ID puede existir en Ollama y plugins. Las sesiones y preferencias actuales guardan proveedor e ID, por lo que son opciones independientes.
- Si aparece no disponible, reactiva o reinstala ese plugin y confirma que aún anuncia el ID.
- Si se eliminó, selecciona expresamente otro. Libre no redirige una selección exacta a un homónimo.
- Sesiones antiguas pueden no tener metadatos. Mantienen enrutamiento por nombre porque no puede inferirse el origen y aparecen como «proveedor no registrado». Vuelve a seleccionar para fijarlo.
- Las personas siguen etiquetadas
persona:<id>. Las nuevas registran Ollama como respaldo; las históricas siguen compatibles.
Problemas de Work
Work no aparece o el entorno no está disponible
Work requiere una cuenta autenticada con acceso —administrador o usuario activo tras abrirlo a todos— y un entorno accesible al backend:
docker info
docker version
Para Docker, confirma que se ejecute y que el usuario del sistema pueda invocar WORK_DOCKER_COMMAND. Instalar mediante npx no instala Docker. Si falta, el resto de la aplicación sigue disponible y Libre no ejecuta comandos del modelo en el host.
Compose activa Work montando el socket. En Kubernetes activa Pod/PVC con work.enabled=true; no montes socket de nodo. Si Compose sigue mostrando Runtime unavailable, la página indica el caso:
| Mensaje | Causa y solución |
|---|---|
The "docker" CLI is not installed… | Imagen personalizada sin docker-cli. Usa la oficial o apunta WORK_DOCKER_COMMAND a un CLI. |
No Docker daemon is reachable… | Se quitó el montaje o se detuvo el daemon. Restáuralo e inicia Docker. |
The Docker socket is mounted but…cannot open | El grupo difiere del contenedor. Define DOCKER_GID en .env y recrea el contenedor. |
La pantalla o el audio de Work se cierran con el WebSocket 1006 y registran screen is unreachable | El backend en contenedor está llamando a su propio loopback. En Docker Desktop usa el valor incluido WORK_DOCKER_PUBLISHED_HOST=host.docker.internal; en Docker Engine nativo define además WORK_PREVIEW_BIND con la puerta de enlace no pública del puente de Docker y recrea Libre WebUI. |
Lee el grupo desde un contenedor porque macOS muestra otro:
echo "DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
alpine stat -c '%g' /var/run/docker.sock)" >> .env
docker compose up -d --force-recreate
El socket concede control equivalente a root; consulta Work: espacios de trabajo aislados.
El modelo no admite herramientas
Work requiere un modelo de chat con herramientas. En Ollama, elige uno cuyas capacidades incluyan tools. Para plugins:
- Confirma que el plugin chat o completion esté activo.
- Confirma el modelo en su lista.
- Confirma una clave para el administrador actual.
- Confirma herramientas en ese modelo exacto.
Libre no redirige una ejecución fallida.
Una solicitud devuelve HTTP 429
La instancia alcanzó un límite de tareas o entornos activos. De forma predeterminada permite dos tareas con contenedor en la instancia y una por usuario. Una vista previa también ocupa capacidad. Espera, detén una vista o revisa WORK_MAX_ACTIVE_RUNTIMES_* y WORK_MAX_TASKS_*.
Falla la instalación de paquetes o la red
Las tareas usan red puente Docker para descargar paquetes e iniciar vistas. Comprueba DNS, proxy, registro y salida en Actividad. Libre no monta claves SSH, credenciales cloud, perfiles de navegador ni socket Docker dentro de la tarea.
Una vista previa no se inicia
- Asegúrate de que el servidor se vincule a
0.0.0.0enWORK_PREVIEW_PORT(4173predeterminado). - Deja el comando opcional vacío para detectar un script
devdepackage.jsonoindex.html, incluso una aplicación anidada única. - Si hay varias o ninguna entrada, introduce el comando de desarrollo. Empieza en
/workspace; usacd <app-directory> && ...para una anidada. - Amplía los detalles del error.
- Detén una vista existente antes de otro comando que necesite el contenedor.
Las URL usan un puerto dinámico de bucle invertido. Navegador y backend deben estar en el mismo equipo. Un navegador conectado a un backend remoto no llega a su bucle y una página HTTPS puede bloquear una vista HTTP como contenido mixto.
No se puede abrir o guardar un archivo
La API acepta texto UTF-8 de hasta 2 MB. Si cambió tras abrirlo, recárgalo para no sobrescribir. El formato se limita a tipos compatibles de menos de 100,000 caracteres y 4,000 líneas; el resaltado se detiene en archivos grandes.
Las ediciones sin guardar quedan como borrador en el navegador, no sustituyen guardar en el espacio persistente.
Se detuvo una tarea o vista
Detener ejecución, vista o reiniciar Libre detiene procesos desechables pero conserva el volumen. Reabre la tarea y reinicia la vista. Eliminar es distinto: tras confirmar, borra definitivamente tarea y espacio.
Problemas de inicio y registro
El primer usuario no es administrador
Solo la primera cuenta de una base nueva se convierte en admin. Las bases existentes conservan roles.
Errores JWT
Define un secreto estable:
JWT_SECRET=replace-with-a-long-random-secret
Cambiar JWT_SECRET invalida sesiones.
Turnstile bloquea el registro
Solo se activa con ambas claves:
TURNSTILE_SITE_KEY=...
TURNSTILE_SECRET_KEY=...
Comprueba que la clave del sitio coincida con el dominio y el secreto sea válido.
Fallan las redirecciones OAuth
Define URL en el proveedor y .env:
BASE_URL=https://your-domain.example
GITHUB_CALLBACK_URL=https://your-domain.example/api/auth/oauth/github/callback
HUGGINGFACE_CALLBACK_URL=https://your-domain.example/api/auth/oauth/huggingface/callback
Problemas del chat documental
Libre WebUI acepta PDF, Office (DOCX/PPTX/XLSX), Markdown, HTML, código y CSV de hasta 10 MB.
Si funciona la búsqueda pero no la recuperación semántica:
- Instala un modelo como
nomic-embed-text. - Activa embeddings en Ajustes.
- Regénéralos desde ajustes o API.
ollama pull nomic-embed-text
La búsqueda por palabras sigue funcionando sin embeddings.
Problemas de vista previa de artefactos
Para juegos o HTML interactivo, pide un archivo HTML completo y autónomo con CSS y JavaScript en línea.
Si necesita teclado:
- Haz clic dentro de la vista.
- Utiliza Abrir en su propia pestaña.
- No dependas de archivos locales ausentes de la respuesta.
Libre puede agrupar bloques comunes index.html + CSS + JavaScript, pero HTML autónomo es más fiable.
Problemas de Docker
El contenedor no llega a Ollama
Usa el archivo externo si Ollama no está en la misma pila:
docker compose -f docker-compose.external-ollama.yml up -d
Los datos no persisten
Monta un volumen persistente y define DATA_DIR si es necesario. La clave se guarda de forma persistente al usar DATA_DIR o Docker.
Restablecer datos locales
Detén la aplicación. Copia y elimina el directorio utilizado. Por defecto es backend/data.
cp -R backend/data backend/data.backup
rm -rf backend/data
Reinicia el backend y crea una cuenta nueva.
Problemas del motor Strands
El motor Strands integrado informa de su estado a cualquier cuenta que pueda usarlo:
curl -H "Authorization: Bearer $LIBRE_ADMIN_TOKEN" \
http://localhost:3001/api/strands/health
Una respuesta 403 significa que el motor no está habilitado para esa cuenta.
La página Strands no aparece
La barra lateral oculta Strands cuando la cuenta no tiene acceso. Revisa Configuración → Gestión de usuarios → Acceso y políticas → Motor Strands. Desactivado bloquea a todo el mundo, administradores incluidos, y Administradores lo oculta a los usuarios normales. Si el control está bloqueado, LIBRE_STRANDS_ACCESS fija el modo: asígnale admins o all-users, o elimina la variable para gestionar el modo desde la interfaz. Cualquier valor distinto de disabled, admins o all-users deja el motor bloqueado en desactivado.
No aparece ningún modelo
Strands solo usa modelos que Libre WebUI ya sirve. Activa Ollama y descarga un modelo de chat, o activa un plugin de proveedor de chat en Configuración → Plugins. A partir de ese momento, la lista de modelos de Strands incluye esos modelos.
Un paso de Work con Strands falla porque no se admiten herramientas
Con Motor: Strands, el agente Strands planifica cada paso mediante llamadas a herramientas, así que el modelo del proveedor debe admitir llamadas a herramientas. Si no las admite, Work indica que el modelo no declara compatibilidad con herramientas (WORK_MODEL_TOOLS_UNSUPPORTED). Elige un modelo compatible con herramientas en el control Modelo de Work y vuelve a ejecutar la tarea.
¿Sigues atascado?
Abre una incidencia con:
- Versión y commit de Libre WebUI
- Método de instalación
- Sistema operativo
- Versión de Node.js
- Versión de Ollama
- Versión de Docker y resultado de
docker infopara Work - Registros del backend alrededor del fallo
- Errores de consola del navegador
- Modelo o proveedor exacto
- Salida de Actividad de Work cuando falle una tarea o vista