Problema
En entornos de self‑hosted backup es frecuente montar un Kopia server dentro de un contenedor Docker y exponerlo mediante un reverse proxy con TLS. El cliente gráfico, Kopia UI, se conecta a esa URL para crear o abrir repositorios remotos. Un error típico que aparece en la UI es:
Connect Error: INTERNAL: internal server error: connect error: error opening repository:
error connecting to API server: unable to establish session for purpose=:
error establishing session: unable to initialize session: rpc error:
code = Unauthenticated desc = unexpected HTTP status code received from server: 401 (Unauthorized);
transport: received unexpected content-type "text/plain; charset=utf-8": EOF
En otras palabras, la petición HTTP llega al servidor, pero la capa de autenticación de la API rechaza al usuario. El síntoma se repite tanto en Windows como en cualquier otro cliente que use el mismo endpoint.
Causa
Los errores 401 Unauthorized en este contexto pueden deberse a varios factores que suelen coincidir en instalaciones “DIY”:
-
Cabeceras de autorización ausentes o mal formateadas
Kopia UI envía la credencial mediante HTTP Basic Auth (usuario:contraseña codificados en base64). Si el reverse proxy no pasa esa cabecera al contenedor, el servidor la interpreta como ausencia de credenciales. -
Terminación TLS en el proxy sin proxy_set_header adecuado
Cuando Nginx/Traefik termina TLS, la petición interna al contenedor es HTTP. Si el proxy no re‑escribe la cabeceraAuthorization, el contenedor nunca la recibe. -
Endpoint de la API mal configurado
El cliente debe apuntar ahttps://host:port/kopia/(o el path que haya configurado el servidor). Un path distinto hace que la petición llegue a la raíz del contenedor, que devuelve 401 por defecto. -
Usuario creado en el servidor con permisos insuficientes
En Kopia, los usuarios pueden estar limitados a ciertos repositories o a ciertos roles. Un usuario que solo tiene permiso de admin pero sin acceso a la ruta solicitada provocará 401. -
Desincronización entre la versión del cliente y la del servidor
Cambios menores en la API (p.ej. en la versión 0.14) pueden romper la negociación de autenticación si una parte está actualizada y la otra no.
Solución
1. Verificar que el proxy reenvíe la cabecera Authorization
En Nginx, la configuración mínima para que la autenticación básica llegue al contenedor es:
server {
listen 443 ssl;
server_name backup.example.fake;
ssl_certificate /etc/letsencrypt/live/backup.example.fake/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/backup.example.fake/privkey.pem;
location / {
proxy_pass http://kopia_server:51515;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# <‑‑ clave
proxy_set_header Authorization $http_authorization;
}
}
La línea proxy_set_header Authorization $http_authorization; asegura que la credencial codificada enviada por Kopia UI no se pierda en la capa de TLS.
2. Confirmar el path de la API
Kopia server expone su API bajo /kopia. Si el contenedor se lanzó con la opción --listen=0.0.0.0:51515, el proxy debe reenviar a esa ruta:
proxy_pass http://kopia_server:51515/kopia/;
En la UI, la URL de conexión debe terminar en /kopia/ (p.ej. https://backup.example.fake/kopia/). O, si se prefiere eliminar el path del proxy, ajustar el location a location /kopia/ { ... }.
3. Revisar los usuarios y sus permisos
Dentro del contenedor, lista los usuarios y verifica los roles:
docker exec -it kopia_server kopia server user list
Si el usuario kopia aparece sin permisos de RepositoryWrite, añádelo:
docker exec -it kopia_server kopia server user add --username=kopia --password=MiClaveSegura --role=admin
Para limitar a un repositorio específico, usa --repo=repo-id. Asegúrate de que la contraseña sea la misma que ingresas en la UI.
4. Alinear versiones
Comprueba la versión del binario dentro del contenedor:
docker exec -it kopia_server kopia version
Y la versión de Kopia UI (se muestra en la barra de título). Si difieren en más de una versión menor, actualiza la que esté desfasada. En la mayoría de los casos, la versión más reciente de ambos componentes elimina incompatibilidades de autenticación.
5. Probar la API directamente
Antes de abrir la UI, usa curl para confirmar que la autenticación funciona:
curl -u kopia:MiClaveSegura -k https://backup.example.fake/kopia/v1/info
El flag -k ignora la verificación del certificado (solo para pruebas). La respuesta JSON con {"version":"...","mode":"server"} indica que la cabecera se está enviando correctamente. Si recibes 401, vuelve a la configuración del proxy.
Cuándo aplicar esta solución
- Síntomas: la UI muestra “401 Unauthorized”, los logs del contenedor indican “rpc error: code = Unauthenticated”.
- Entorno: Kopia server en Docker, acceso a través de un reverse proxy con TLS (Nginx, Traefik, Caddy, etc.).
- No aplica: si el cliente se conecta directamente al contenedor (sin proxy) y la autenticación falla; en ese caso el problema suele estar en la creación del usuario o en la contraseña.
Código
# 1. Crear usuario con permisos admin (ejecución dentro del host)
docker exec -it kopia_server kopia server user add \
--username=kopia \
--password=MiClaveSegura \
--role=admin
# 2. Verificar que el usuario exista
docker exec -it kopia_server kopia server user list
# 3. Probar la API con curl
curl -u kopia:MiClaveSegura -k https://backup.example.fake/kopia/v1/info
Verificación
- Reinicia Nginx (o el proxy que uses) para cargar la nueva configuración.
sudo nginx -s reload - Abre Kopia UI y crea/abre un repositorio remoto apuntando a
https://backup.example.fake/kopia/. - La UI debe cargar la lista de repositorios sin mostrar el mensaje de error.
- En los logs del contenedor (
docker logs kopia_server) no debe aparecerUnauthenticateddespués de la conexión.
Notas adicionales
- Certificados autofirmados: si decides no usar LetsEncrypt, agrega la CA al almacén de confianza de Windows o usa la opción
-kencurlsolo para pruebas. En producción, un certificado válido evita errores de “certificate verification failed” que a veces se confunden con 401. - Header stripping en Cloudflare: si el proxy está detrás de Cloudflare o similar, verifica que la opción “Disable HTTP Header Rewrite” esté activada; de lo contrario Cloudflare puede eliminar la cabecera
Authorization. - Logs de Kopia: habilita
KOPIA_LOGGING=debugal lanzar el contenedor para obtener trazas más detalladas de la negociación de sesión. - Persistencia de datos: siempre monta un volumen para
/app/kopia-repo(o el directorio que uses) para evitar perder la configuración de usuarios al recrear el contenedor.
Con estos ajustes la comunicación entre Kopia UI en Windows y el servidor Kopia en Docker debería ser estable, segura y, lo más importante, libre de errores 401.