MinIO
MinIO is a self-hosted object store that speaks the Amazon S3 API, written in Go and shipped as one binary. It stores objects as erasure-coded shards across local drives, with no separate metadata database. The community edition is AGPLv3, but the GitHub repository was archived on 2026-04-25 and binary builds stopped after RELEASE.2025-09-07; MinIO, Inc. now points users to AIStor Free (single node, proprietary licence) or paid AIStor Enterprise. It fits as an S3 endpoint for app files on a cluster that already runs it, but new deployments should weigh SeaweedFS, Garage or Ceph RGW first.
MinIO is an object storage server that implements the Amazon S3 API. Applications that already use an S3 SDK can point at a MinIO endpoint and store files on their own hardware or cluster, with buckets, access keys, presigned URLs and bucket policies working as they do on AWS. For years it was the default S3 endpoint for self-hosted stacks and local development. Its community edition is no longer maintained upstream, and that change shapes every decision on this page.
What it is
A single Go binary (minio server) that serves the S3 API on port 9000 and, in older builds, a web console on a second port. It stores data on local drives or directories. It needs no database, no metadata service and no coordinator; each object carries its own metadata file (xl.meta) next to its data.
Licence and status. The community source is GNU AGPLv3 (documentation is CC BY 4.0). The project's status changed in three steps, all visible in the GitHub repository and its releases:
| Date | Change |
|---|---|
| 2025-05-24 | RELEASE.2025-05-24T17-08-30Z (marked Breaking) deprecated the embedded admin console and moved it to the separate object-browser project. LDAP and OIDC logins for the UI were removed from the open-source build and moved to AIStor. The STS APIs still work. |
| 2025-09-07 | RELEASE.2025-09-07T16-13-09Z, the last release published with pre-built binaries, RPM, DEB and APK packages. |
| 2025-10-16 | RELEASE.2025-10-15T17-29-55Z, a source-only security release that fixes CVE-2025-62506. |
| 2026-04-25 | The repository was archived and is read-only. The README states: "THIS REPOSITORY IS NO LONGER MAINTAINED." |
The README says the community edition "is now distributed as source code only" and that legacy binaries on GitHub Releases and dl.min.io "will not receive updates". The MinIO Operator and the mc client repositories are archived too. The Go SDK, minio-go, still receives commits.
What MinIO, Inc. ships now. The commercial product is AIStor, under the proprietary MinIO Software License. The pricing page lists two tiers. AIStor Free is a "full-featured, single-node deployment architecture" with community Slack support, free of charge, and redistribution is prohibited. AIStor Enterprise is distributed, and its subscription is priced on usable capacity after erasure-coding overhead. docs.min.io now documents AIStor, not the community server.
How it works
A MinIO deployment is one or more server pools. Each pool is a set of nodes and drives, divided into erasure sets. When an object is written, MinIO hashes the object name to pick an erasure set, splits the object into data and parity shards, and writes one shard to each drive in the set. A read needs enough shards to rebuild the object, so a set survives the loss of as many drives as it has parity shards. A single-node, single-drive deployment has no erasure coding and no redundancy; the drive is the only copy.
Identity is built in. The root user comes from MINIO_ROOT_USER and MINIO_ROOT_PASSWORD. Additional users and service accounts get S3-style IAM policies, and the server stores that IAM state on its own drives. Every request is signed with AWS Signature V4, so the server checks the signature, then evaluates the policy, then touches data. Bucket notifications can push an event to a webhook, queue or database target after each change.
Step 1 of 5. The SDK sends PutObject with a Signature V4 Authorization header, computed from the secret key and the request contents.
Single erasure set shown. A multi-pool deployment first picks the pool, then the erasure set, from the object name.
The design has no metadata tier, so a MinIO cluster is only drives and processes. Two limits follow from this. An erasure set's size is fixed when the pool is created, so capacity grows by adding a new pool, not by adding drives to an existing set. Listing a large bucket also means walking metadata across drives, which is slower than a store with an indexed metadata service.
When to use it
Reach for it when:
- A cluster already runs MinIO and the apps need an S3 endpoint for uploads, exports or generated files. The S3 API is stable, so the server can be swapped later without changing app code.
- Local development or CI needs an S3 endpoint that behaves like AWS for SigV4, presigned URLs and multipart uploads.
- Building from source, pinning a release and owning the patches is acceptable. Or AIStor Free's single-node terms and its proprietary licence fit.
Skip it when:
- A new deployment needs an object store with upstream maintenance. The community project is archived and will not get further security fixes.
- The workload needs multi-node redundancy without a commercial contract. AIStor Free is single node, and the community distributed mode has no maintainer.
- It is a backup target. A backup store has to outlive the data it protects, so an unmaintained server is the wrong place for it.
- The data must sit on a network file system. MinIO is designed for local drives (the docs recommend XFS) and advises against NFS-backed volumes.
At a glance
Core concepts
- Bucket / object / key — the S3 model. Keys are flat strings;
/is only a naming convention. - Erasure set — the group of drives that holds the shards of an object. Parity (
EC:N) sets how many drives the set can lose. - Server pool — a set of nodes and drives added as a unit. New objects are placed across pools weighted by free space.
- Access key / service account — the credentials an app signs with. A service account inherits a parent user's policy, which it can restrict further.
- Versioning, object lock, lifecycle — S3-compatible features: keep old versions, block deletes for a retention period, expire or transition objects by rule.
- Bucket notifications — events sent to webhooks, queues or databases on create, delete or access.
Key facts
| Fact | Value |
|---|---|
| API | Amazon S3 (Signature V4), port 9000 by default |
| Licence (community) | GNU AGPLv3, source only since late 2025 |
| Last binary release | RELEASE.2025-09-07T16-13-09Z |
| Last source release | RELEASE.2025-10-15T17-29-55Z (fixes CVE-2025-62506) |
| Upstream status | Repository archived 2026-04-25 |
| Build requirement | Go 1.24 or later |
| Default root credentials | minioadmin:minioadmin (change before first use) |
| Commercial line | AIStor Free (single node) and AIStor Enterprise |
Compared with the rivals
| Aspect | MinIO (community) | SeaweedFS | Garage | Ceph RGW |
|---|---|---|---|---|
| Licence | AGPLv3 | Apache 2.0 | AGPLv3 | LGPL |
| Upstream maintenance | Archived | Active | Active | Active |
| Metadata | Per-object files on the drives | Master and filer services | Built-in, replicated | RADOS cluster |
| Redundancy | Erasure coding | Replication, erasure coding for warm data | Replication across zones | Replication or erasure coding |
| Operational weight | One binary | Several small services | One binary | Heavy (a full Ceph cluster) |
How to integrate
Build from source. The README gives go install. Pin a tag, and build the container image in-house, because the upstream Dockerfile expects a locally built minio binary.
go install -v github.com/minio/[email protected]
minio server /data --console-address :9001
Single-node Deployment on Kubernetes. This is the smallest useful shape: one replica, one PersistentVolumeClaim, root credentials from a Secret. The image name is a placeholder for an in-house build.
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio
spec:
replicas: 1
strategy: {type: Recreate} # one pod owns the volume
selector: {matchLabels: {app: minio}}
template:
metadata: {labels: {app: minio}}
spec:
containers:
- name: minio
image: registry.example.com/minio:RELEASE.2025-10-15T17-29-55Z
args: ["server", "/data", "--console-address", ":9001"]
envFrom:
- secretRef: {name: minio-root} # MINIO_ROOT_USER, MINIO_ROOT_PASSWORD
ports:
- {name: s3, containerPort: 9000}
readinessProbe:
httpGet: {path: /minio/health/ready, port: 9000}
livenessProbe:
httpGet: {path: /minio/health/live, port: 9000}
volumeMounts:
- {name: data, mountPath: /data}
volumes:
- name: data
persistentVolumeClaim: {claimName: minio-data}
Create a bucket and an app-scoped key with the mc client (archived, but older builds still work against the server):
mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"
mc mb local/app-files
mc admin user svcacct add local "$MINIO_ROOT_USER" --policy ./app-files-rw.json
Point an S3 SDK at it. Use path-style addressing unless MINIO_DOMAIN and wildcard DNS are configured for virtual-host buckets.
import boto3
from botocore.config import Config
s3 = boto3.client(
"s3",
endpoint_url="http://minio:9000",
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
region_name="us-east-1",
config=Config(s3={"addressing_style": "path"}),
)
url = s3.generate_presigned_url("get_object",
Params={"Bucket": "app-files", "Key": "exports/report.csv"}, ExpiresIn=900)
In the GL stack
MinIO runs on the production cluster at RELEASE.2025-09-07. It is the S3-compatible store for application files: the products write uploads and generated files to it through standard S3 clients.
The stack treats MinIO as a store to keep running, not one to grow. The community edition is archived upstream, so the backup store does not use MinIO. Velero, the Postgres and Neo4j backups and the etcd snapshots for every cluster write to SeaweedFS on the management cluster instead. That keeps backups off an unmaintained server, and it means a MinIO failure cannot take the backups with it. Because apps reach MinIO only through the S3 API, a later move of the app-file buckets to another S3-compatible server is a data copy plus an endpoint change.
The running release is the last one with published binaries. It predates the source-only October 2025 release that fixes CVE-2025-62506.
Gotchas
- The pinned binary is missing a security fix. CVE-2025-62506 (CVSS 8.1) lets a restricted service account or STS account create a new service account that inherits its parent's full privileges. The advisory lists no workaround, and the fix exists only as source in RELEASE.2025-10-15T17-29-55Z. Until it is built and rolled out, avoid restricted service accounts as a security boundary.
- The console is not what older guides show. Since RELEASE.2025-05-24 the embedded console is an object browser only, and LDAP and OIDC UI logins are gone from the open-source build. Do admin work with
mc adminor the admin API. - Default credentials are
minioadmin:minioadmin. Always setMINIO_ROOT_USERandMINIO_ROOT_PASSWORD, and give apps service accounts, never the root key. - Path-style vs virtual-host addressing. Many SDKs default to
bucket.hostURLs. WithoutMINIO_DOMAINand wildcard DNS, set path-style in the client or requests fail with DNS or signature errors. - Clock skew breaks signing. SigV4 rejects requests whose timestamp is far from server time (
RequestTimeTooSkewed). Keep NTP running on clients and nodes. - Presigned URLs embed the host. A URL signed for an in-cluster hostname fails if the browser reaches the server through a different hostname, because the host is part of the signature. Sign with the public endpoint.
- Erasure sets do not resize. Plan pool size up front; expansion means adding a pool.
Risks
- No upstream maintenance. With the repository archived, future CVEs will get no fix from upstream. Any deployment now depends on in-house builds, a community fork, or a move to AIStor.
- Licence. AGPLv3 obligations apply if a modified server is offered over a network. AIStor Free is proprietary, single node, and prohibits redistribution. Read the terms before replacing one with the other.
- Vendor direction. Features moved from the open build to AIStor before the archive (UI identity logins, the admin console). Expect the gap between the two to widen.
- Ecosystem decay. The Operator and
mcrepositories are archived too, and Helm charts and blog posts will drift out of date. - Low lock-in. The S3 API is the integration surface, so leaving MinIO is mostly a data-migration task.
Alternatives
- SeaweedFS — Apache 2.0, active, with an S3 gateway in front of a volume store built for many small files. Pick it for a maintained, permissive replacement on a homelab or small cluster.
- Garage — AGPLv3, one binary, geo-distributed replication from Deuxfleurs. Pick it for a small, low-ops S3 store spread across a few sites or nodes.
- Ceph RGW (via Rook on Kubernetes) — the S3 gateway of Ceph. Pick it when block, file and object storage at scale justify running a Ceph cluster.
- Amazon S3 or Cloudflare R2 — managed object storage. Pick it when running a storage server is not worth the time and egress costs are understood.
Related
- SeaweedFS — the object store that holds the backups.
- Velero — cluster backups, written to SeaweedFS.
- Postgres and CloudNativePG — the databases that sit next to the object store.
- Data layer of a Kubernetes homelab — how the stores fit together.
- minio/minio on GitHub — the archived repository and its README notice.
- MinIO releases — the last binary and source releases.
- GHSA-jjjj-jwhf-8rgr — the CVE-2025-62506 advisory.
- AIStor pricing — AIStor Free and Enterprise terms.
