El error 401 UNAUTHORIZED al descargar quay.io/minio/minio no se arregla con credenciales: MinIO dejó ese repositorio sin acceso público y falla con cualquier etiqueta. El arreglo es cambiar la imagen por cgr.dev/chainguard/minio o por pgsty/silo, en tu compose, en tu despliegue de Kubernetes o en los valores del chart de Helm. Esta guía reproduce el error en Docker, en k3s, en BuildKit y con el chart oficial, explica por qué Quay responde 401 y prueba cada arreglo. Lo probé el 27 de octubre de 2026 en Linux arm64 con Docker 29.5.2, Compose v2.40.3 y k3s v1.37.0. Tienes la versión en inglés de esta guía.

Puntos clave

  • quay.io/minio/minio y quay.io/minio/mc devuelven 401 con cualquier etiqueta: latest, RELEASE.2025-10-15T17-29-55Z y las versiones de 2024 que fija el chart de Helm.
  • Quay da a un usuario anónimo un permiso vacío sobre minio/minio, el mismo 401 que da para un repositorio que no existe, mientras que el espacio minio aún publica 94 repositorios.
  • quay.io/minio/aistor/minio sí se descarga, pero es AIStor: sin licencia, crear un bucket falla con Access denied. No license is installed.
  • cgr.dev/chainguard/minio:latest (RELEASE.2026-10-23T20-06-51Z) y pgsty/silo:RELEASE.2026-10-26T00-00-00Z arrancaron en Compose y en k3s.
  • En el chart de Helm de MinIO 5.4.0, cambia image y mcImage por pgsty/silo y el despliegue arranca.

Si el mensaje que ves es pull access denied for minio/minio, vienes de Docker Hub: la guía de pull access denied for minio/minio cubre ese caso y la compilación desde el código fuente.

El error: failed to resolve reference quay.io/minio/minio 401 UNAUTHORIZED

El mensaje dice que el registro rechazó la petición del manifiesto porque no estás autorizado, y sale igual en docker pull, en docker compose pull y en docker compose up cuando la imagen no está en caché. Esto es lo que obtuve el 27 de octubre de 2026:

$ docker pull quay.io/minio/minio:RELEASE.2025-10-15T17-29-55Z
Error response from daemon: unknown: failed to resolve reference
"quay.io/minio/minio:RELEASE.2025-10-15T17-29-55Z": unexpected status
from HEAD request to https://quay.io/v2/minio/minio/manifests/
RELEASE.2025-10-15T17-29-55Z: 401 UNAUTHORIZED

$ docker compose up -d
 minio Pulling
 minio Error unknown: failed to resolve reference "quay.io/minio/minio:
 RELEASE.2025-10-15T17-29-55Z": unexpected status from HEAD request to
 https://quay.io/v2/minio/minio/manifests/RELEASE.2025-10-15T17-29-55Z:
 401 UNAUTHORIZED

En tu terminal cada mensaje ocupa una sola línea. Probé latest, RELEASE.2025-09-07T16-13-09Z, RELEASE.2025-04-22T22-12-26Z y RELEASE.2025-10-15T17-29-55Z, la última versión publicada: las cuatro fallan igual. quay.io/minio/mc también. No depende de la etiqueta, así que buscar una versión antigua no sirve.

¿Cómo se ve el mismo 401 en Kubernetes, BuildKit y otras herramientas?

Cada cliente envuelve el 401 en su propio texto, pero la causa es la misma. Esta tabla recoge lo que devolvió cada uno con la misma imagen:

Herramienta Mensaje que verás
docker pull, Compose unexpected status from HEAD request ... 401 UNAUTHORIZED
Kubernetes (containerd) failed to pull and unpack image ... 401 UNAUTHORIZED, luego ImagePullBackOff
docker build con COPY --from failed to resolve source metadata for quay.io/minio/mc:latest
skopeo 1.22.3 unauthorized: access to the requested resource is not authorized
crane UNAUTHORIZED: access to the requested resource is not authorized

En Kubernetes el error aparece en los eventos del pod. Lo reproduje en un k3s v1.37.0 dentro de Docker con un kubectl run de la imagen; este es el evento que mostró kubectl describe pod:

Warning  Failed  kubelet  Failed to pull image
"quay.io/minio/minio:RELEASE.2025-10-15T17-29-55Z": failed to pull and
unpack image "quay.io/minio/minio:RELEASE.2025-10-15T17-29-55Z": failed
to resolve reference "quay.io/minio/minio:RELEASE.2025-10-15T17-29-55Z":
unexpected status from HEAD request to https://quay.io/v2/minio/minio/
manifests/RELEASE.2025-10-15T17-29-55Z: 401 UNAUTHORIZED
Warning  Failed  kubelet  Error: ErrImagePull
Warning  Failed  kubelet  Error: ImagePullBackOff

El caso de BuildKit pasa desapercibido. Un Dockerfile con COPY --from=quay.io/minio/mc:latest /usr/bin/mc /usr/bin/mc siguió construyendo en mi máquina porque la imagen estaba en caché; con docker build --pull --no-cache falló con el 401. Tu CI, que empieza sin caché, lo verá a la primera.

¿Por qué quay.io devuelve 401 si la imagen era pública?

Porque MinIO quitó el acceso público al repositorio, y Quay responde 401 tanto a un repositorio privado como a uno inexistente. Lo comprobé pidiendo a quay.io/v2/auth un token anónimo de lectura. Para minio/kes el token concede "actions":["pull"]; para minio/minio concede "actions":[]. Con ese token, el manifiesto devuelve 401 en minio/minio, en minio/mc y en un repositorio inventado, minio/zz-no-existe-xyz.

El resto del espacio minio sigue abierto. La API de Quay lista 94 repositorios públicos, entre ellos kes, warp, operator y una serie entera bajo aistor/. Solo faltan el servidor y el cliente de la edición comunitaria.

La incidencia 1402 de registry-stack[1] fecha el cambio hacia las 13:00 UTC del 24 de septiembre de 2026. Una ejecución de su CI descargó la imagen a las 12:50 y la siguiente falló.

El motivo está en el README del repositorio de MinIO[2], archivado desde abril: "The MinIO community edition is now distributed as source code only. We will no longer provide pre-compiled binary releases for the community version." El mismo texto remite a AIStor Free y AIStor Enterprise como alternativas. No hay imagen comunitaria oficial en ningún registro. La búsqueda de GitHub muestra el goteo de proyectos rotos desde entonces: LibreChat[3] el 25 de septiembre, un taller de Snowflake sobre Iceberg[4] el 10 de octubre y otros más este mes.

¿Sirve la imagen quay.io/minio/aistor/minio?

No como sustituto gratuito. quay.io/minio/aistor/minio:latest se descarga sin cuenta y se identifica como RELEASE.2026-09-19T17-05-25Z con License: MinIO AIStor License. Arranca y formatea el disco, pero sin licencia se queda en modo bloqueado, y así lo dice el propio registro del contenedor:

WARN: No valid license found, running in offline mode. All S3
operations are denied. Please install a valid license using
'mc license update' to restore service.

$ mc mb a/pruebas
mc: <ERROR> Unable to make bucket `a/pruebas`. Access denied. No
license is installed. Please install a valid license using
'mc license update' to enable service.

AIStor Free existe, pero es otro producto, con otra licencia que tienes que instalar en el servidor. Si cambias la imagen sin más, tu aplicación recibirá Access denied en cada petición S3. No probé con una licencia, así que no puedo decirte cómo se comporta con una instalada.

Arreglo en Docker Compose: qué imagen usar ahora

Cambia la línea image: por una de estas dos. Las dos se descargan sin cuenta, publican variantes arm64 y amd64 y las mantiene alguien hoy:

Imagen Versión el 27 de octubre de 2026 Usuario Quién la mantiene
cgr.dev/chainguard/minio:latest RELEASE.2026-10-23T20-06-51Z 65532 Chainguard, desde su fork
pgsty/silo:RELEASE.2026-10-26T00-00-00Z RELEASE.2026-10-26T00-00-00Z root Pigsty, fork comunitario

Chainguard compila la imagen desde su fork de MinIO[5]. El fork recibió un arreglo de seguridad el 22 de septiembre y dependencias nuevas el 23 de octubre de 2026. Silo[6], el fork de Pigsty, tiene 4340 estrellas y publicó versiones el 18 y el 26 de octubre. Este es el compose que dejé funcionando con Chainguard:

services:
  minio:
    image: cgr.dev/chainguard/minio:latest
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    volumes:
      - datos:/data
    ports:
      - "127.0.0.1:9000:9000"
volumes:
  datos:

Con un volumen nuevo arrancó a la primera y /minio/health/live devolvió 200; con Silo en la misma línea image:, también. Si tu volumen ya tiene datos escritos por la imagen antigua, que corría como root, Chainguard necesita antes un chown a 65532. La guía de pull access denied for minio/minio muestra el error exacto y el comando. Chainguard solo publica latest en su plan gratuito, así que fija la imagen por resumen si quieres despliegues reproducibles; Silo sí tiene etiquetas por versión.

Arreglo en Kubernetes y en el chart de Helm de MinIO

En Kubernetes cambias la imagen del despliegue, y Kubernetes sustituye el pod que está en ImagePullBackOff. Lo probé en k3s con un Deployment que usaba la imagen de Quay:

kubectl set image deployment/minio minio=cgr.dev/chainguard/minio:latest
kubectl rollout status deployment/minio

El pod nuevo pasó a Running, pero el registro de MinIO mostró Rename across devices not allowed, porque no tenía volumen en /data. Con un emptyDir o un PersistentVolumeClaim montado en /data y securityContext: {fsGroup: 65532} en el pod, arrancó limpio y /minio/health/live respondió HTTP/1.1 200 OK. Si aún no tienes un clúster de pruebas, la guía para instalar k3s en tu homelab monta uno en una máquina.

El chart oficial de Helm falla por partida doble. La versión 5.4.0 de charts.min.io, la última publicada, fija quay.io/minio/minio:RELEASE.2024-12-18T13-15-44Z para el servidor y quay.io/minio/mc:RELEASE.2024-11-21T17-21-54Z para el trabajo que crea los buckets. Tras un helm install quedaron los dos pods en ImagePullBackOff. Este fichero de valores lo arregla:

image:
  repository: docker.io/pgsty/silo
  tag: RELEASE.2026-10-26T00-00-00Z
mcImage:
  repository: docker.io/pgsty/silo
  tag: RELEASE.2026-10-26T00-00-00Z

Aplícalo con helm upgrade tu_release minio/minio --reuse-values -f valores-silo.yaml. Elegí Silo porque su imagen trae /usr/bin/mc, que es lo que llama el trabajo del chart, además del docker-entrypoint.sh que usa el servidor.

El servidor arrancó como Silo Object Storage Server y, desde un pod con la misma imagen, mc mb creó un bucket contra el servicio. El trabajo del chart no llegó a crearlo en mi prueba: arranqué k3s sin CoreDNS para ahorrar memoria y no resolvía el nombre del servicio. En un clúster con DNS no tendrás ese problema.

Arreglo en un Dockerfile que copia mc desde la imagen

Si tu Dockerfile copia el cliente con COPY --from=quay.io/minio/mc, cópialo desde Silo. Su /usr/bin/mc es un enlace simbólico, así que copia el binario real, mcli, y dale el nombre de siempre:

FROM mirror.gcr.io/library/alpine:3.22
COPY --from=docker.io/pgsty/silo:RELEASE.2026-10-26T00-00-00Z \
     /usr/bin/mcli /usr/bin/mc

La imagen resultante devolvió mc version RELEASE.2026-10-26T00-00-00Z y el binario ocupa 28,7 MB. Si tu caso es el contenedor createbuckets de un compose, la guía de pull access denied for minio/mc prueba tres sustitutos para ese patrón.

Si prefieres no depender de un fork

Las dos imágenes anteriores son forks, y el código de MinIO está archivado. Te quedan dos caminos.

El primero es compilar MinIO y mc tú mismo y subir el resultado a tu registro privado de imágenes Docker. La guía de Docker Hub incluye un Dockerfile de 22 líneas probado. El segundo es salir de MinIO: la migración de MinIO a Garage copia los buckets con rclone a un almacén más ligero, y la migración a RustFS conserva consola, usuarios y versionado.

Quédate en un fork si necesitas una función de MinIO que el destino no tenga. En ese caso fija la versión y vigila los avisos de seguridad del fork que elijas, porque el repositorio original ya no publica ninguno.

Preguntas frecuentes

¿Se arregla con docker login quay.io?

No lo probé con una cuenta de Quay. El token anónimo para minio/minio sale sin permisos y la API del repositorio responde Requires authentication, la misma respuesta que da para un repositorio inventado. MinIO no ha anunciado acceso con cuenta a esas imágenes, así que no hay motivo para esperar que una cuenta personal lo arregle.

¿Por qué mi compose arranca en un servidor y en otro no?

Porque el servidor que arranca tiene la imagen en caché y Compose no la descarga si ya está. En mi máquina, docker compose up -d arrancó con quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z en caché, y docker compose pull falló con el 401. Una máquina nueva, un runner de CI o un nodo de Kubernetes recién añadido no tienen esa caché.

¿Son de fiar las imágenes de Chainguard y Silo?

Las dos tienen mantenimiento activo y un fork público que puedes revisar. Chainguard es una empresa de imágenes de contenedor; su catálogo de imágenes mínimas firma cada imagen. Silo es un proyecto comunitario de Pigsty sin relación con MinIO. Las dos mantienen la licencia AGPLv3 del original, según su salida de --version.

Conclusión

El 401 de quay.io/minio/minio es definitivo desde el 24 de septiembre de 2026 y no depende de la etiqueta ni de tu configuración. Para salir del paso, cambia la imagen por cgr.dev/chainguard/minio:latest o por pgsty/silo con etiqueta fija, en Compose, en Kubernetes o en los valores image y mcImage del chart de Helm. No uses la imagen AIStor de Quay sin licencia, porque rechaza todas las operaciones S3. Después decide con calma si te quedas en un fork o migras a Garage o RustFS.

Fuentes: [1] MinIO, README del repositorio archivado[2], [2] registry-stack, incidencia 1402 sobre el 401 de Quay[1], [3] Quay, API del repositorio minio/minio[7], [4] MinIO, valores del chart de Helm[8], [5] Chainguard, imagen de MinIO[9], [6] Chainguard, fork de MinIO[5], [7] Pigsty, fork Silo[6], [8] LibreChat, incidencia 259[3], [9] Snowflake Labs, incidencia 9 de apache-iceberg-from-zero[4].

Fuentes

  1. incidencia 1402 de registry-stack
  2. README del repositorio de MinIO
  3. LibreChat
  4. Snowflake sobre Iceberg
  5. su fork de MinIO
  6. Silo
  7. Quay, API del repositorio minio/minio
  8. MinIO, valores del chart de Helm
  9. Chainguard, imagen de MinIO