Cómo arreglar el error 401 UNAUTHORIZED de quay.io/minio/minio en Docker y Kubernetes
Índice de contenidos
- Puntos clave
- El error: failed to resolve reference quay.io/minio/minio 401 UNAUTHORIZED
- ¿Cómo se ve el mismo 401 en Kubernetes, BuildKit y otras herramientas?
- ¿Por qué quay.io devuelve 401 si la imagen era pública?
- ¿Sirve la imagen quay.io/minio/aistor/minio?
- Arreglo en Docker Compose: qué imagen usar ahora
- Arreglo en Kubernetes y en el chart de Helm de MinIO
- Arreglo en un Dockerfile que copia mc desde la imagen
- Si prefieres no depender de un fork
- Preguntas frecuentes
- ¿Se arregla con docker login quay.io?
- ¿Por qué mi compose arranca en un servidor y en otro no?
- ¿Son de fiar las imágenes de Chainguard y Silo?
- Conclusión
- Fuentes
El 401 UNAUTHORIZED de quay.io/minio/minio no es un fallo de credenciales: MinIO dejó ese repositorio sin acceso público en septiembre de 2026 y falla con cualquier etiqueta. Cambia la imagen por cgr.dev/chainguard/minio o por pgsty/silo en Compose, Kubernetes o Helm; la copia AIStor de Quay sí se descarga, pero sin licencia rechaza todo.
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/minioyquay.io/minio/mcdevuelven 401 con cualquier etiqueta:latest,RELEASE.2025-10-15T17-29-55Zy 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 espaciominioaún publica 94 repositorios. quay.io/minio/aistor/miniosí se descarga, pero es AIStor: sin licencia, crear un bucket falla conAccess denied. No license is installed.cgr.dev/chainguard/minio:latest(RELEASE.2026-10-23T20-06-51Z) ypgsty/silo:RELEASE.2026-10-26T00-00-00Zarrancaron en Compose y en k3s.- En el chart de Helm de MinIO 5.4.0, cambia
imageymcImageporpgsty/siloy 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
Código fuente
Accede a todo el código fuente de este artículo en GitHub.
Ver en GitHub