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/minio y minio/mc devuelven 404 en la API de Docker Hub, aunque el espacio minio sigue publicando otros 20 repositorios.
  • quay.io/minio/minio responde 401 a cualquier etiqueta, también a la RELEASE.2025-09-07T16-13-09Z que fijaba la guía de instalación de este blog.
  • Tres sustitutos se descargan hoy sin cuenta: cgr.dev/chainguard/minio, pgsty/silo y 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 chown previo, MinIO se para con file 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

  1. ventana de Docker Hub
  2. incidencia de registry-stack
  3. repositorio archivado de MinIO
  4. MinIO para linux-amd64 en dl.min.io
  5. CVE-2025-62506
  6. RELEASE.2025-10-15T17-29-55Z
  7. MinIO Client, repositorio archivado
  8. Chainguard, imagen de MinIO
  9. Chainguard, fork de MinIO
  10. Pigsty, fork Silo
  11. Quay, API del repositorio minio/minio