Cómo arreglar pull access denied for minio/minio en Docker
Índice de contenidos
- Puntos clave
- ¿Qué significa el error pull access denied for minio/minio?
- ¿Por qué tampoco funciona quay.io/minio/minio?
- ¿Cuándo y por qué retiró MinIO sus imágenes?
- Arreglo inmediato: qué imagen de MinIO se descarga hoy
- Con la imagen de Chainguard
- Con el fork pgsty/silo
- Si tu servidor aún tiene la imagen en caché
- Cómo compilar MinIO y mc desde el código fuente con Docker
- ¿Qué imagen uso para el cliente mc?
- Cuándo compensa migrar a Garage o RustFS
- Preguntas frecuentes
- ¿Se arregla con docker login?
- ¿Pierdo mis datos al cambiar de imagen?
- ¿Sirve fijar el resumen sha256 de la imagen antigua?
- Conclusión
- Fuentes
El error pull access denied for minio/minio aparece porque MinIO retiró sus imágenes de Docker Hub en septiembre de 2026, y quay.io exige cuenta desde el día 24. Cambia la imagen de tu compose por cgr.dev/chainguard/minio, por el fork pgsty/silo o por una compilada desde el código: tus datos siguen sirviendo.
El error pull access denied for minio/minio significa que la imagen ya no existe donde tu compose la busca, y se arregla cambiando de imagen, no con docker login. MinIO borró minio/minio y minio/mc de Docker Hub en septiembre de 2026, y desde el 24 de ese mes quay.io también rechaza las descargas anónimas. Esta guía reproduce los tres mensajes que vas a ver, te da tres imágenes que se descargan hoy y comprueba que arrancan sobre tus datos. Lo probé el 30 de septiembre de 2026 en Linux arm64 con Docker 29.5.2 y Compose v2.40.3. Tienes la versión en inglés de esta guía.
Puntos clave
minio/minioyminio/mcdevuelven 404 en la API de Docker Hub, aunque el espaciominiosigue publicando otros 20 repositorios.quay.io/minio/minioresponde 401 a cualquier etiqueta, también a laRELEASE.2025-09-07T16-13-09Zque fijaba la guía de instalación de este blog.- Tres sustitutos se descargan hoy sin cuenta:
cgr.dev/chainguard/minio,pgsty/siloy una imagen propia compilada con un Dockerfile de 22 líneas. - Los tres arrancaron sobre el directorio de datos de otro MinIO y devolvieron los 200 objetos con sus sumas SHA-256 intactas.
- La imagen de Chainguard corre con el usuario 65532: sin un
chownprevio, MinIO se para confile access denied.
¿Qué significa el error pull access denied for minio/minio?
Significa que el registro no encuentra un repositorio público con ese nombre, y en este caso es literal: el repositorio ya no está. Docker usa el mismo texto para un repositorio privado y para uno inexistente, y por eso sugiere docker login. Estos son los mensajes exactos que obtuve el 30 de septiembre de 2026, primero con docker pull y luego con docker compose up:
$ docker pull minio/minio
Using default tag: latest
Error response from daemon: pull access denied for minio/minio,
repository does not exist or may require 'docker login'
$ docker compose up -d
minio Pulling
minio Error pull access denied for minio/minio, repository does not
exist or may require 'docker login'
Error response from daemon: pull access denied for minio/minio,
repository does not exist or may require 'docker login'
En tu terminal cada mensaje sale en una sola línea; aquí lo he partido para que quepa. docker pull minio/mc falla con el mismo texto cambiando el nombre. La API de Docker Hub confirma el diagnóstico: hub.docker.com/v2/repositories/minio/minio/ y .../minio/mc/ devuelven 404 con object not found, mientras que el listado del espacio minio sigue mostrando 20 repositorios, entre ellos warp, operator y sidekick.
¿Por qué tampoco funciona quay.io/minio/minio?
Porque MinIO cerró también la copia de Quay. Si seguiste el consejo de pasar a quay.io/minio/minio, ahora ves un 401 en lugar del mensaje de Docker Hub:
$ docker pull quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z
Error response from daemon: unknown: failed to resolve reference
"quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z": unexpected status
from HEAD request to https://quay.io/v2/minio/minio/manifests/
RELEASE.2025-09-07T16-13-09Z: 401 UNAUTHORIZED
quay.io/minio/mc responde igual. La API de Quay de ese repositorio pide autenticación, mientras que la de otros repositorios públicos, como coreos/etcd, contesta 200. No es un límite de peticiones ni una caída del registro.
¿Cuándo y por qué retiró MinIO sus imágenes?
MinIO dejó de distribuir binarios e imágenes de la edición comunitaria, y la retirada llegó por fases a lo largo de 2026. MinIO no ha publicado un aviso con fechas, así que las de los registros salen de incidencias de terceros que midieron el cambio:
| Fecha | Qué cambió | Fuente |
|---|---|---|
| 25 de abril de 2026 | minio/minio en GitHub pasa a archivado, solo código fuente |
GitHub |
| 14 de julio de 2026 | minio/mc en GitHub pasa a archivado |
GitHub |
| 11 de septiembre de 2026 | Docker Hub borra minio/minio y minio/mc (entre las 18:12 y las 20:13 UTC) |
dandi-cli |
| 24 de septiembre de 2026 | quay.io empieza a responder 401 hacia las 13:00 UTC | registry-stack |
| 30 de septiembre de 2026 | dl.min.io ya devuelve 410 para los binarios |
mi prueba |
La ventana de Docker Hub[1] la midió un colaborador de dandi-cli. La de Quay se documenta en una incidencia de registry-stack[2]: una ejecución descargó la imagen a las 12:50 UTC y la siguiente ya falló. El README del repositorio archivado de MinIO[3] remite a AIStor Free, un producto con licencia propia, y dice que la edición comunitaria "is now distributed as source code only".
El servidor de descargas es el más explícito. Una petición a cualquier binario, como el MinIO para linux-amd64 en dl.min.io[4], devuelve 410 con este texto: "The open-source MinIO Server, MinIO Client (mc) and MinIO KES projects are archived and no longer maintained. MinIO does not provide product support, security updates, or security advisories for them".
Arreglo inmediato: qué imagen de MinIO se descarga hoy
Cambia la línea image: de tu compose por una de estas tres. Comprobé que cada una se descarga sin cuenta, que trae variante arm64 y amd64 y que arranca sobre los datos de un MinIO anterior:
| Imagen | Versión probada | Etiquetas | Quién la mantiene |
|---|---|---|---|
cgr.dev/chainguard/minio:latest |
RELEASE.2026-09-22T19-25-18Z | solo latest |
Chainguard, desde su fork |
pgsty/silo:RELEASE.2026-09-16T00-00-00Z |
RELEASE.2026-09-16T00-00-00Z | por versión | Pigsty, fork comunitario |
| imagen propia | RELEASE.2025-10-15T17-29-55Z | la que pongas | tú |
Probé la variante arm64 de las tres; la amd64 solo la vi listada en el manifiesto. Hay una cuarta que también se descarga, bitnamilegacy/minio:latest, pero su binario es una compilación de desarrollo de mayo de 2025 y no la recomiendo.
Con la imagen de Chainguard
La imagen de Chainguard es la sustitución más directa: su punto de entrada ya es el binario minio, así que tu command: de siempre funciona sin cambios. Este es el servicio que dejé en marcha, con las credenciales en un fichero .env al lado:
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:
- ./data:/data
ports:
- "127.0.0.1:9000:9000"
- "127.0.0.1:9001:9001"
restart: unless-stopped
Antes de arrancarla sobre datos existentes, cambia su propietario. La imagen oficial corría como root y la de Chainguard corre como el usuario 65532, así que mi primer intento terminó así:
Error: unable to rename (/data/.minio.sys/tmp -> ...) file access
denied, drive may be faulty, please investigate
FATAL Unable to initialize backend: Unable to write to the backend
Un chown desde un contenedor desechable lo resuelve, y no necesitas sudo en el host:
docker compose down
docker run --rm -v "$PWD/data:/data" mirror.gcr.io/library/busybox:1.37 \
chown -R 65532:65532 /data
docker compose up -d
Tras el cambio, MinIO arrancó, /minio/health/live devolvió 200 y descargué los 200 objetos de prueba con sumas SHA-256 idénticas a las originales. El bucket con versionado conservó sus dos versiones. Si usas un volumen con nombre en lugar de ./data, el chown es igual cambiando la ruta de montaje.
Ten en cuenta dos límites de esta imagen. Chainguard solo publica latest en su plan gratuito: pedir RELEASE.2026-09-22T19-25-18Z como etiqueta devuelve MANIFEST_UNKNOWN, y el resumen cambió de sha256:bd014394 a sha256:4692462f entre el 27 y el 30 de septiembre. Fíjala por resumen si quieres builds reproducibles. Tampoco trae curl ni wget, así que un healthcheck que los llame falla; la guía de healthchecks en Docker Compose explica cómo plantearlo sin ellos.
Con el fork pgsty/silo
Silo es un fork comunitario de MinIO que publica Pigsty, con etiquetas por versión y la consola web completa. El proyecto se llamaba pgsty/minio hasta el 6 de agosto de 2026; el binario ahora se llama silo y el cliente, mcli. Cambiar solo la línea image: del compose anterior bastó:
image: docker.io/pgsty/silo:RELEASE.2026-09-16T00-00-00Z
Su script de entrada antepone silo a tu command: y acepta las mismas variables MINIO_ROOT_USER y MINIO_ROOT_PASSWORD. Corre como root, así que no necesita el chown. Arrancó sobre la misma copia de datos, mcli ls listó los 200 objetos y las sumas coincidieron. La contrapartida es que dependes de un proyecto pequeño que no está afiliado a MinIO.
Si tu servidor aún tiene la imagen en caché
Si tu MinIO sigue en marcha es porque la imagen está en la caché local, y eso te da margen. Compose solo descarga la imagen cuando no la tiene, así que docker compose up -d arrancó sin problema con quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z en caché. En cambio, docker compose pull y docker compose up -d --pull always fallaron con el 401 de Quay. Lo mismo le pasará a cualquier herramienta que actualice imágenes sola.
Mientras decides, guarda una copia de la imagen y no ejecutes docker system prune -a:
docker image ls --digests | grep -E 'minio/(minio|mc)'
docker save quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z \
| gzip > minio-imagen.tar.gz
docker load -i minio-imagen.tar.gz
El primer comando lista las imágenes de MinIO que conservas y sus resúmenes, el segundo exporta el servidor a un fichero y el tercero lo restaura en otra máquina. En mi caché, la imagen de Quay ocupaba 227 MB y el fichero comprimido, 57 MB. Recuerda que esa versión de 2025 no incluye el arreglo de la CVE-2025-62506[5], una escalada de privilegios que el aviso califica como alta, con 8,1 sobre 10. Sirve para ganar tiempo, no como destino.
Cómo compilar MinIO y mc desde el código fuente con Docker
Compilar tu propia imagen es la única vía oficial que queda. Las notas de RELEASE.2025-10-15T17-29-55Z[6], la última versión publicada y la que corrige la CVE-2025-62506, lo dicen así: "For container environments, please clone the source and build the latest container". El atajo que proponen, make docker, ya no funciona, porque el Dockerfile del repositorio empieza por FROM minio/minio:latest:
ERROR: failed to build: failed to solve: minio/minio:latest: failed to
resolve source metadata for docker.io/minio/minio:latest: pull access
denied, repository does not exist or may require authorization
Este Dockerfile de 22 líneas compila el servidor y el cliente en una imagen de Go y los copia a una Alpine. Las imágenes base vienen del espejo de Google para no depender de Docker Hub:
FROM mirror.gcr.io/library/golang:1.24-alpine AS build
ARG MINIO_TAG=RELEASE.2025-10-15T17-29-55Z
ARG MINIO_TIME=2025-10-15T17:29:55Z
ARG MC_TAG=RELEASE.2025-08-13T08-35-41Z
ARG MC_TIME=2025-08-13T08:35:41Z
ENV CGO_ENABLED=0 MINIO_RELEASE=RELEASE MC_RELEASE=RELEASE
RUN apk add --no-cache git
RUN git clone -q --depth 1 -b "$MINIO_TAG" https://github.com/minio/minio /minio
RUN git clone -q --depth 1 -b "$MC_TAG" https://github.com/minio/mc /mc
WORKDIR /minio
RUN go build -trimpath -tags kqueue -o /out/minio \
-ldflags "$(go run buildscripts/gen-ldflags.go "$MINIO_TIME")"
WORKDIR /mc
RUN go build -trimpath -tags kqueue -o /out/mc \
-ldflags "$(go run buildscripts/gen-ldflags.go "$MC_TIME")"
FROM mirror.gcr.io/library/alpine:3.22
RUN apk add --no-cache ca-certificates
COPY --from=build /out/minio /out/mc /usr/bin/
EXPOSE 9000 9001
ENTRYPOINT ["minio"]
CMD ["server", "/data", "--console-address", ":9001"]
Las variables MINIO_RELEASE y MC_RELEASE y la marca de tiempo hacen que el binario se identifique como RELEASE.…; sin ellas sale DEVELOPMENT.…. Constrúyela con docker build -t minio-local:RELEASE.2025-10-15T17-29-55Z . y pon ese nombre en tu image:. La mía se identificó así:
$ docker run --rm minio-local:RELEASE.2025-10-15T17-29-55Z --version
minio version RELEASE.2025-10-15T17-29-55Z (commit-id=9e49d5e7a648...)
Runtime: go1.24.13 linux/arm64
El commit-id coincide con el de la etiqueta en GitHub. La imagen pesa 51,6 MB, corre como root y trae wget, así que tu healthcheck puede llamar a /minio/health/live. Arrancó sobre los mismos datos y devolvió los 200 objetos intactos. Desde aquí los parches son cosa tuya: nadie publicará versiones nuevas en el repositorio archivado.
¿Qué imagen uso para el cliente mc?
minio/mc falla igual que el servidor, y tienes tres sustitutos. El más directo es cgr.dev/chainguard/minio-client:latest, cuyo punto de entrada ya es mc; lo usé para cargar y comprobar todos los datos de esta prueba:
docker run --rm --network mi_red_de_compose \
-v "$PWD/mc:/tmp/mc" -e MC_CONFIG_DIR=/tmp/mc \
cgr.dev/chainguard/minio-client:latest \
alias set local http://minio:9000 tu_usuario tu_clave_secreta
La variable MC_CONFIG_DIR guarda el alias en un directorio montado, porque el usuario 65532 no puede escribir en /root. Esa imagen se identifica como DEVELOPMENT.GOGET y no dice de qué versión sale. Si necesitas saberlo, la imagen compilada del apartado anterior incluye mc RELEASE.2025-08-13T08-35-41Z, y pgsty/silo trae su propio cliente, mcli. Si tu mc solo hace mb y cp en un script de arranque, cualquier cliente S3 como rclone o la interfaz de línea de comandos de AWS te sirve igual.
Cuándo compensa migrar a Garage o RustFS
Cambiar de imagen devuelve MinIO a la vida, pero no le da futuro: el código upstream está archivado y los parches dependen de Chainguard, de Pigsty o de ti. Si montaste MinIO con la guía para instalar MinIO con Docker y lo usas como almacén S3 de copias, adjuntos o registros, tienes dos destinos probados en este blog. La migración de MinIO a Garage es la opción ligera, pero Garage no tiene versionado, bloqueo de objetos ni políticas de bucket. La migración de MinIO a RustFS es la más parecida a MinIO, con consola, usuarios IAM y versionado.
Quédate en un fork si tu aplicación usa alguna función de MinIO que el destino no tenga, y compruébalo contra la tabla de compatibilidad de cada guía. En ese caso, fija la imagen por versión o por resumen y ponte un recordatorio para revisar sus avisos de seguridad.
Preguntas frecuentes
¿Se arregla con docker login?
No hay indicios de que ayude. Docker Hub ya no lista minio/minio ni minio/mc, y MinIO no ha anunciado ningún acceso con cuenta a esas imágenes. El mensaje sugiere docker login porque Docker no distingue entre un repositorio privado y uno borrado. No lo probé con una cuenta de Docker Hub ni de Quay.
¿Pierdo mis datos al cambiar de imagen?
No en mi prueba. Escribí 200 objetos y un bucket versionado con un MinIO de 2025 y los leí sin cambios con Chainguard, con Silo y con la imagen compilada. El formato en disco es el mismo porque las tres salen del mismo código. Haz una copia del directorio de datos antes del cambio de todos modos.
¿Sirve fijar el resumen sha256 de la imagen antigua?
No, fijar el resumen no esquiva el problema. docker pull quay.io/minio/minio@sha256:14cea493… también recibió un 401, porque Docker pregunta al registro por el manifiesto igual que con una etiqueta. Solo funciona si la imagen ya está en la caché local o en un registro espejo tuyo.
Conclusión
pull access denied for minio/minio no tiene arreglo desde tu lado del registro: MinIO retiró las imágenes de Docker Hub el 11 de septiembre de 2026 y cerró Quay el 24. Para el cambio mínimo, usa cgr.dev/chainguard/minio y haz el chown de los datos. Si prefieres etiquetas por versión, usa pgsty/silo, y si quieres controlar el binario, compílalo tú. Después, dedica una tarde a decidir si te quedas en un fork o migras a Garage o RustFS.
Fuentes
Código fuente
Accede a todo el código fuente de este artículo en GitHub.
Ver en GitHub