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 se vinculan a ruta, autenticación, definición y fuente. Guárdalas otra vez tras cambiar. Una antigua sin vínculo solo migra en una ruta incluida 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.
¿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