Problema

Al intentar añadir el repositorio oficial de Docker en una instalación limpia de Ubuntu 26.04, apt devuelve un mensaje similar a:

Error: Conflicting values set for option Signed-By regarding source https://download.docker.com/linux/ubuntu/ resolute:
  /usr/share/keyrings/docker-archive-keyring.gpg != /etc/apt/keyrings/docker.asc
Error: The list of sources could not be read.

El error indica que la misma fuente APT tiene dos entradas que especifican rutas diferentes para la clave GPG (Signed-By). Cuando apt procesa la lista de fuentes, no puede decidir cuál usar y aborta la operación.

Este patrón se repite en cualquier distro basada en APT que haya recibido configuraciones de repositorios mixtas (por ejemplo, guías que usan /usr/share/keyrings/ y otras que usan /etc/apt/keyrings/). El síntoma típico es la imposibilidad de ejecutar apt update después de añadir o modificar un archivo .list o .sources.

Causa

  1. Duplicación de fuentes
    La mayoría de los tutoriales crean una entrada en /etc/apt/sources.list.d/docker.list que incluye Signed-By=/usr/share/keyrings/docker-archive-keyring.gpg. Si el usuario ya había creado una entrada manual o ejecutó un script que usó /etc/apt/keyrings/docker.asc, ambas líneas quedan en el mismo archivo o en archivos diferentes, provocando el conflicto.

  2. Migración de rutas de keyring
    Desde Ubuntu 22.04, la ubicación recomendada para claves de terceros cambió a /etc/apt/keyrings/. Las guías más antiguas todavía apuntan a /usr/share/keyrings/. Cuando se mezclan versiones de la documentación, el gestor de paquetes interpreta que la misma URL de repositorio tiene dos claves distintas.

  3. Persistencia de archivos de clave
    Al desinstalar Docker, los scripts de purge a veces dejan la clave en una ruta pero no eliminan la referencia en la lista de fuentes. Un intento posterior de reinstalar Docker vuelve a crear la clave en la nueva ubicación, generando la colisión.

  4. Errores tipográficos o permisos
    Un archivo .list con una ruta incompleta o con permisos que impiden la lectura de la clave también puede desencadenar el mismo mensaje, ya que apt interpreta la ruta como inexistente y la compara con la que sí existe.

Solución

La estrategia consiste en normalizar la definición del repositorio: una única entrada, una única ruta de clave y la eliminación de cualquier referencia residual. Los pasos son aplicables tanto a Ubuntu 26.04 como a cualquier versión que use apt y signed-by.

1. Eliminar fuentes y claves conflictivas

sudo rm -f /etc/apt/sources.list.d/docker.list
sudo rm -f /etc/apt/sources.list.d/docker*.list
sudo rm -f /usr/share/keyrings/docker-archive-keyring.gpg
sudo rm -f /etc/apt/keyrings/docker.asc

Con esto garantizamos que no quede rastro de configuraciones anteriores.

2. Crear la carpeta de keyrings (si no existe)

sudo mkdir -p /etc/apt/keyrings

3. Descargar la clave oficial y guardarla en la ubicación única

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

docker.gpg es un nombre genérico; lo importante es que la ruta sea la misma que usaremos en la fuente.

4. Añadir la fuente con la opción Signed-By apuntando a la clave recién guardada

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Este comando genera una única línea, sin duplicados, y usa la ruta de clave que acabamos de crear.

5. Actualizar el índice y proceder con la instalación

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

Si apt update finaliza sin errores, la colisión está resuelta.

Cuándo aplicar esta solución

  • Síntomas: apt update falla con “Conflicting values set for option Signed-By” o “The list of sources could not be read”.
  • Entorno: Ubuntu, Debian o cualquier derivado que utilice archivos .list y la opción Signed-By.
  • Escenarios válidos: instalación de Docker, Kubernetes, o cualquier herramienta que añada repositorios externos mediante GPG.
  • No aplicar: si la máquina usa apt-key (obsoleto) y no tiene archivos .list con Signed-By. En ese caso, migra primero a la nueva metodología antes de usar esta guía.

Código

# 1. Limpiar configuraciones previas
sudo rm -f /etc/apt/sources.list.d/docker.list
sudo rm -f /usr/share/keyrings/docker-archive-keyring.gpg
sudo rm -f /etc/apt/keyrings/docker.asc

# 2. Preparar directorio de claves
sudo mkdir -p /etc/apt/keyrings

# 3. Descargar y convertir la clave GPG
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 4. Registrar el repositorio con Signed-By único
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 5. Actualizar índices e instalar Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

Verificación

  1. Comprobar que apt update no muestra errores

    sudo apt update
    

    La salida debe listar paquetes de Docker sin advertencias.

  2. Validar que Docker está activo

    sudo systemctl status docker
    

    El estado debe ser active (running).

  3. Ejecutar un contenedor de prueba

    sudo docker run --rm hello-world
    

    La salida debe confirmar que el motor funciona correctamente.

Si alguno de los pasos falla, revisa que la ruta de la clave en /etc/apt/sources.list.d/docker.list coincida exactamente con el archivo creado en /etc/apt/keyrings/docker.gpg.

Notas adicionales

  • Mantén una única ruta de clave: cuando añadas repositorios de terceros, elige siempre /etc/apt/keyrings/ y usa la misma ruta en Signed-By. Evita mezclar con /usr/share/keyrings/.
  • Automatiza con scripts: si despliegas varios nodos, encapsula los comandos anteriores en un script idempotente. Un simple if [ -f /etc/apt/keyrings/docker.gpg ]; then exit 0; fi evita re‑descargas.
  • Migración futura: Ubuntu planea eliminar apt-key en versiones posteriores. Adoptar la práctica de Signed-By ahora previene roturas inesperadas cuando la herramienta se retire.
  • Permisos: el archivo de clave debe ser legible por apt (propietario root, 644). Si cambias manualmente los permisos, apt puede volver a lanzar errores de “cannot read key”.
  • Depuración rápida: apt-cache policy muestra la URL y la clave asociada a cada repositorio. Úsalo para confirmar que no haya entradas duplicadas.

Con estos pasos, cualquier conflicto de Signed-By al instalar Docker (o cualquier otro paquete externo) se resuelve de forma limpia y reproducible.