This is the multi-page printable view of this section. .
Posts
- 1: SILO at One Year: What Actually Changed Since Upstream MinIO?
- 2: MinIO Fork, Promise Kept
- 3: MinIO Is Dead, Long Live MinIO
- 4: MinIO Is Dead. Which Next?
- 5: MinIO is Dead
Essays and analysis about MinIO, S3-compatible object storage, and the SILO community fork.
1 - SILO at One Year: What Actually Changed Since Upstream MinIO?
On October 15, 2025, MinIO shipped its final public open-source release, RELEASE.2025-10-15T17-29-55Z (commit 9e49d5e7a648). Over the next four months, upstream placed the repository into “maintenance mode,” deleted the minio/console repository outright, and in February 2026 archived the main server repository—routing all subsequent CVE patches and bug fixes exclusively to its commercial AIStor product.
On October 26, 2026, SILO tagged RELEASE.2026-10-26T00-00-00Z (commit c3ad836aed0d). Across 376 days, the server repository accumulated 604 commits, evolving alongside its companion repositories silo-console, mcli, and silo-pkg.
A question we hear often from operators evaluating the fork is straightforward: Over the past year, did SILO merely rebrand the binary and apply surface-level CVE patches, or did it fix substantive storage and protocol bugs? Compared with the final upstream MinIO release, what actually changed?
Here is the short answer: SILO preserved MinIO’s erasure-coding storage layout (xl.meta v1.3), HighwayHash bitrot protection, and fundamental read/write quorum rules, while focusing a full year of engineering on security boundaries, S3 protocol and checksum correctness, replication and lifecycle convergence, failed-write rollback and multi-pool safety, and a restored administration console and CLI.
| Area | Key Substantive Changes (2025-10-15 → 2026-10-26) |
|---|---|
| Security & Authorization | Patched 7 post-fork CVEs (OIDC algorithm confusion, LDAP STS enumeration and brute-force, replication SSE header injection, S3 Select unbounded record OOM, unsigned-trailer signature bypass, Snowball extraction authorization bypass, and /rmpl path traversal) plus 18 SN-2026-* security boundary hardenings (enforced SigV4 SignedHeaders for X-Amz-* operational headers, policy condition key isolation, bucket-level write action boundaries, service-account delegation ceilings, Object Lock bypass validation, and durable IAM revocations against stale-event resurrection) |
| S3 Protocol & Checksums | Replaced upstream’s NotImplemented stubs with full per-bucket CORS persistence and OPTIONS preflight; implemented conditional DELETE (If-Match) and multi-pool conditional PUT / CompleteMultipartUpload; fixed plaintext checksums and logical part sizes across multipart uploads, CopyObject, SSE-C, and server-side compression; changed tampered-encryption errors from HTTP 206 to 500 |
| Replication & Lifecycle | Preserved FULL_OBJECT checksum types during multipart replication initiation (#255); preserved raw SSE-C ciphertext and seals across trusted replication peers; added modification timestamps to object tags and Object Lock retention for out-of-order convergence; prevented versioned lifecycle expiration from deleting remote tier data when only adding a delete marker (#253) |
| Storage & Multi-Pool Safety | Two-stage multi-pool bulk deletion (#257), migration version checks, LIST recovery under drive disagreement (#239), and storage RPC delete options for overwrite rollback; existing timeout/cancellation semantics remain, including the possibility of late commits, delayed rollback and stale reads |
| Console & mcli | Restored and rebuilt the full administration UI in SILO Console v2.5.1 (<3 MB zero-telemetry bundle, EN/ZH toggle, cursor pagination, Tasks center, Metrics V3, high-latency WebSocket diagnostic repairs); shipped mcli 20261026 with read-only checksum verify, nonzero exit codes on partial or permission failures, and safe mirror delete propagation |
| Operations & Delivery | Wired --read-header-timeout / MINIO_READ_HEADER_TIMEOUT (30s absolute HTTP/1 header deadline); added trusted-proxy settings (MINIO_API_TRUSTED_PROXIES) and native silo healthcheck; permanently removed self-update and SUBNET call-home; built a verified multi-arch supply chain on Go 1.27.3, UBI 9.8 / distroless images, RPM/DEB/APK packages, Windows ZIP archives, GPG signatures, SPDX SBOMs, and Sigstore attestations |
Equally important are the boundaries that have not changed:
- No distributed fencing, and no claim that every consistency problem is solved. Late commits after lease expiration or network partitions remain possible; strict generation read refusal, automatic cross-pool read recovery, public persistent
ListMultipartUploadsscanning (#79), access-frequency pool tiering, and multi-pool overwrite affinity (#245) were tested and withdrawn or deferred when their capacity or availability costs proved unacceptable. - No head-to-head full-cluster throughput benchmark between the two tags. We record targeted microbenchmarks and amortized overhead checks, not synthetic cluster-wide throughput claims.
- On-disk compatibility does not mean arbitrary mixed-version operation or rolling downgrade. Durable IAM revocations (
siloParentRevocation) and replication metadata tombstones require coordinated upgrades across participating nodes.
The sections below walk through each area in detail, with exact commit references, design records, and operational boundaries.
1. Baseline and Product Stack: What Changed and What Stayed the Same
Our comparison uses two fixed points:
- Upstream baseline:
minio/minioRELEASE.2025-10-15T17-29-55Z(commit9e49d5e7a648f00e26f2246f4dc28e6b07f8c84a, October 15, 2025). Note: between that final release and archiving the repo in February 2026, upstream merged 9 unreleased commits (such as POST policy tag constraints infa18589d1cand conditional PUT read-quorum adjustments in18f97e70b1), which never shipped in an upstream release and were addressed independently in SILO. - SILO target:
pgsty/siloRELEASE.2026-10-26T00-00-00Z(commitc3ad836aed0d8a7d23c2e44a5eaa3009d08525e3), released alongside mcli / KES 20261026, Console v2.5.1, and silo-pkg v3.15.2. See the release notes and component matrix.
Across 9e49d5e7a648..c3ad836aed0d, pgsty/silo contains 604 reachable commits spanning feature and security repairs, regression suites, packaging, and documentation. The sections below organize those changes by delivered runtime behavior.
The Four-Component Coordinated Stack
Because the server embeds the Console frontend and imports mc administration packages alongside shared policy and encryption libraries, maintaining the server alone is not enough. SILO maintains a coordinated four-component product graph (plus optional external KES):
| Component | Upstream 2025-10-15 State |
SILO 20261026 State |
Key Evolution |
|---|---|---|---|
Server (pgsty/silo) |
Go 1.24.0, minio binary |
Go 1.27.3, silo binary (c3ad836aed0d) |
Retains github.com/minio/minio module path; delivers 7 CVE fixes, 18 security boundary hardenings, and storage/replication repairs |
Console (pgsty/silo-console) |
Stripped-down v1.7.7 (object browser only) |
v2.5.1 (fff1618d9abb) |
Upstream deleted minio/console; SILO restored the full admin console with a <3 MB zero-telemetry bilingual frontend |
Client (pgsty/mc) |
mc cf909e1063a9 |
mcli 20261026 (0ceb298cdcd0) |
Shipped as mcli (avoiding collision with Midnight Commander mc), adding checksum verify and honest error exit codes |
Shared Pkg (pgsty/silo-pkg) |
minio/pkg/v3 v3.1.3 |
v3.15.2 (0416eb1f4505) |
Maintained directly as github.com/pgsty/silo-pkg/v3 for IAM policy evaluation, condition key isolation, TLS trust, and KMS |
S3 SDK (minio/minio-go/v7) |
v7.0.91 |
v7.4.2-0.20261025165926-320af050c445 |
Uses the verified upstream module commit (including short-stream multipart, negative-offset ReadAt, and batch-delete fixes) |
KMS (pgsty/kes) |
External optional service | KES 20261026 (e9b4f1acebc1) |
Go 1.27.3; OpenBao KV v2 and local Moto Secrets Manager compatibility checks; updated AWS and GCP clients |
Foundations Intentionally Preserved
So existing MinIO deployments can switch to pgsty/silo in place without data migration or client changes, SILO keeps the core storage and wire contracts unchanged:
- Erasure coding and bitrot protection: Reed-Solomon erasure coding and per-block HighwayHash256 verification remain unchanged.
- Read and write quorum rules: Read quorum remains $K$ (data shards); write quorum remains $K$ when data and parity shard counts differ, and $K+1$ when data shards equal parity shards (for example, 16-drive 12+4 uses R12/W12, while 8+8 uses R8/W9).
- On-disk format and system namespace:
xl.metastays at version1.3and.minio.sysretains its layout, allowing existing drives to mount directly. - Wire and configuration compatibility:
MINIO_*,MC_*, andCONSOLE_*environment variables,/minio/health/*probes,/minio/v2/metrics/*and/minio/metrics/v3scrape endpoints, andX-Minio-*headers remain supported (see the compatibility overview and migration guide).
2. Security, Authentication, and Authorization: 7 CVEs and 18 Security Boundary Hardenings
Because SILO retains the github.com/minio/minio Go module path while upstream advisories publish open-ended affected version ranges, automated scanners frequently flag SILO for every historical MinIO CVE.
To separate fact from scanner noise: vulnerabilities such as CVE-2025-62506 (service-account privilege escalation), CVE-2025-31489, and CVE-2025-27414 were already fixed in upstream’s 2025-10-15 baseline. By contrast, the 7 CVEs below were disclosed after 2025-10-15, left unpatched in upstream open-source MinIO, and fixed and verified in SILO:
| CVE / Advisory | Severity | Root Cause and Impact | SILO Fix and Code Evidence |
|---|---|---|---|
| CVE-2026-33322 | Critical (9.8) | OIDC JWT algorithm confusion: when a token header specified HMAC (HS256), upstream verified it using the OIDC ClientSecret as a symmetric key, letting anyone with ClientSecret forge arbitrary identities including consoleAdmin |
Enforce asymmetric JWKS public-key verification only and reject HMAC-signed OIDC tokens (cmd/jwt.go, internal/config/identity/openid/) |
| CVE-2026-33419 | High | LDAP STS endpoint leaked whether usernames existed and lacked rate limiting, enabling username enumeration and password brute-forcing for STS credentials | Unify bind-failure authentication errors and enforce sliding-window rate limiting keyed by trusted client IP + normalized username without penalizing successful logins (cmd/sts-handlers.go) |
| CVE-2026-34204 | High | Unauthenticated X-Minio-Replication-* headers on ordinary PUT/COPY requests could inject broken encryption metadata and render objects permanently unreadable |
Strip unauthorized replication headers and SSE replication metadata at request ingress (cmd/auth-handler.go, cmd/object-handlers-common.go) |
| CVE-2026-39414 | High | S3 Select accumulated newline-free CSV or JSON Lines streams without bound, allowing a single request to trigger an out-of-memory (OOM) crash | Enforce strict per-record byte limits in the CSV and JSON Lines parsers (internal/s3select/) |
| CVE-2026-41145 | High | STREAMING-UNSIGNED-PAYLOAD-TRAILER write paths bypassed signature verification on specific routes, allowing anonymous or forged-signature object writes |
Enforce full authentication and signature validation across all aws-chunked and unsigned-trailer ingress paths (cmd/auth-handler.go) |
| CVE-2026-40344 | High | Snowball archive batch-extraction upload path lacked entry-point authentication and per-entry authorization checks | Require caller authentication at ingress and evaluate bucket/prefix policy authorization for every extracted archive entry (cmd/bucket-handlers.go, cmd/object-handlers.go) |
| CVE-2026-42600 | High | Internode storage endpoint /rmpl (ReadMultiple) lacked drive-root path containment, allowing path traversal outside the drive root |
Remove the unused ReadMultiple endpoint from the internode storage REST protocol and enforce strict drive-root path containment across all storage RPC handlers (cmd/storage-rest-server.go) |
18 SN-2026-* Security Boundary Hardenings
Beyond public CVEs, adversarial code review and multi-node testing uncovered 18 additional security boundary defects tracked in our Security Advisories ledger:
- SigV4 SignedHeaders Integrity and Policy Condition Isolation (SN-2026-011, SN-2026-003):
- Upstream allowed callers to attach unsigned
X-Amz-*operational headers (such as governance bypass, tagging, or checksum headers) to an otherwise valid SigV4 request. SILO requires everyX-Amz-*operational header present on the request to be covered bySignedHeaders. - Upstream populated IAM policy condition maps directly from client headers and query parameters, allowing callers to spoof server-authoritative condition keys such as
s3:prefix,s3:versionid,s3:ExistingObjectTag/*, oraws:PrincipalType. SILO isolates server-authoritative condition keys insilo-pkgand bindss3:VersionIdchecks to the actual target version inDeleteObjectsandGetObject.
- Upstream allowed callers to attach unsigned
- Bucket-Level Write Boundaries, Version-Deletion Authorization, and Admin Action Splits (SN-2026-004, SN-2026-005, SN-2026-009 and 010, SN-2026-017):
- Tightened resource ARN matching for 12 bucket-level write actions (
s3:CreateBucket,s3:DeleteBucket,s3:PutBucketPolicy,s3:PutLifecycleConfiguration, etc.) so object wildcard grants (arn:aws:s3:::bucket/*) or barearn:aws:s3:::ARNs cannot mutate bucket configurations. - Require
s3:DeleteObjectVersionfor permanent deletion of an explicit version ID, includingnull; an ordinary delete that creates a delete marker still usess3:DeleteObject. Batch deletion checks each entry independently. - Split user status toggling out of
admin:CreateUserintoadmin:EnableUser/admin:DisableUser; separated self-service password changes intoadmin:ChangeMyPassword(see password-permission migration); and enforced parent-account ownership checks across IAM admin access-key creation, inspection, and listing endpoints.
- Tightened resource ARN matching for 12 bucket-level write actions (
- Service-Account Delegation Ceilings and Object Lock Governance Bypass (SN-2026-015 and 016):
- Fixed inline session-policy evaluation so parent
Denyrules are never dropped when the inline policy omits a matchingAllow, and re-verified live parent privileges on temporary STS and service-account sessions. - Required
x-amz-bypass-governance-retention: truewhenPutObjectoverwrites aGOVERNANCE-locked object, and validated retention XML payloads before evaluating Object Lock governance bypass inPutObjectRetention.
- Fixed inline session-policy evaluation so parent
- Durable IAM Revocations, Policy Reload Lock Isolation, and LDAP Long DNs (SN-2026-013):
- Previously, in multi-node and site-replicated clusters, delayed site-replication events or missed peer notifications could resurrect deleted users, policies, or service accounts. SILO persists deletion tombstones, revision numbers, and parent revocation cutoffs (
siloParentRevocation) across both object-backed IAM and STS enumeration, and reloads committed state on peer delete notifications. - Moved slow IAM policy loads and KMS decryption outside the hot authentication-cache lock while propagating KMS request cancellation (design record); fixed LDAP
StartTLSprecedence and hex-escaped long DN path-component limits (design record).
- Previously, in multi-node and site-replicated clusters, delayed site-replication events or missed peer notifications could resurrect deleted users, policies, or service accounts. SILO persists deletion tombstones, revision numbers, and parent revocation cutoffs (
3. S3 Protocol Completeness and End-to-End Checksums
On the S3 protocol surface, SILO focused on three goals: implementing stubbed-out bucket APIs, aligning multi-pool conditional write semantics, and ensuring end-to-end plaintext checksum and size accuracy across multipart, encrypted, and compressed objects.
| Feature / Scenario | Upstream MinIO (2025-10-15) |
SILO (20261026) |
Design Record |
|---|---|---|---|
| Per-bucket CORS | GetBucketCors/PutBucketCors/DeleteBucketCors returned NotImplemented stubs |
Full per-bucket CORS XML persistence (up to 100 rules, 64 KiB), dynamic OPTIONS preflight matching, site replication, and bucket metadata export/import |
Per-Bucket CORS |
Conditional DELETE |
No If-Match support on DELETE |
Single-object DELETE supports If-Match: "<etag>" and If-Match: * under the shared object lock; batch DeleteObjects does not support per-entry ETag conditions |
Conditional DELETE |
Multi-pool conditional PUT & multipart completion |
Checked only the target write pool, allowing stale pool copies to accept outdated ETags or reject current ones | Resolves the logical current object across all storage pools (including draining pools) before evaluating If-Match / If-None-Match |
Multi-Pool Object Consistency |
| Server-computed part checksums | A checksum-enabled multipart upload rejected parts without explicit checksum headers, including copied parts | Computes plaintext part checksums using the algorithm declared at upload initialization, before compression or encryption, and persists them in xl.meta; uploads without a declared algorithm do not acquire a default CRC32C checksum |
Part Checksums |
CompleteMultipartUpload verification |
Permissive on duplicate part numbers, missing checksums, or FULL_OBJECT type mismatches |
Enforces strictly ascending part numbers (InvalidPartOrder on duplicates) and validates part checksums and FULL_OBJECT / COMPOSITE rollups |
Checksum Integrity Repairs |
CopyObject / UploadPartCopy checksums |
Server-side copies of encrypted or compressed objects could copy ciphertext bitrot hashes and omit ChecksumType in responses |
Computes or verifies checksums against plaintext logical bytes and returns accurate ChecksumType in CopyObjectResult / CopyPartResult |
Checksum Integrity Repairs |
| SSE-C same-object key rotation & zero-byte objects | In-place CopyObject with a new SSE-C key updated metadata without re-encrypting payload bytes; zero-byte SSE-C objects and part attributes skipped unsealing |
Rewrites ciphertext on same-object SSE-C key rotation and validates customer keys on zero-byte SSE-C reads and GetObjectAttributes part listings |
SSE-C Key Rotation, Zero-Byte Validation |
| Logical part sizes for encrypted/compressed objects | GetObjectAttributes and ?partNumber=N could report physical encrypted/compressed shard sizes |
Returns exact plaintext logical part sizes across GetObjectAttributes and part-number GET/HEAD requests |
Multipart Part Logical Size |
ObjectTampered HTTP status |
Returned HTTP 206 Partial Content when stored encryption metadata was tampered with |
Returns HTTP 500 (XMinioObjectTampered) so clients and caches never treat tampered objects as valid partial responses |
ObjectTampered 500 Status |
DNS federation CopyObject |
Cross-cluster federated copies could stream raw .minio.sys ciphertext, leaving the destination object undecryptable |
Streams decrypted plaintext via standard S3 client reads and re-seals at the destination | Federated CopyObject |
4. Replication and Lifecycle Correctness
In clusters running active-active replication or remote tiering, the most damaging bugs are silent divergence between sites or premature deletion of tiered data. Over the past year, SILO fixed six replication and lifecycle failure modes:
| Area | Upstream Behavior and Risk | SILO Behavior |
|---|---|---|
Multipart FULL_OBJECT checksum replication (#255) |
When replicating a multipart object with a CRC32/CRC32C FULL_OBJECT checksum, the source omitted x-amz-checksum-type: FULL_OBJECT on NewMultipartUpload, causing the target to validate as COMPOSITE and fail CompleteMultipartUpload with BadDigest |
Propagates ChecksumType in putReplicationOpts so multipart replication and CopyObject share the full checksum header contract (design record) |
| SSE-C replica integrity | Replicating SSE-C objects regenerated KMS/DARE seals or corrupted the customer-key seal on the target replica | Preserves raw SSE-C ciphertext, random IVs, and cryptographic seals across trusted replication peers (design record) |
| Timestamped tag deletion & out-of-order convergence | Tag deletion sent an empty string without advancing a revision timestamp, letting delayed replication events resurrect deleted tags; SSE-KMS copies also dropped tag revision timestamps | Adds replication-tag-modtime timestamps and deletion tombstones, preserves timestamps across SSE-KMS copies, and rejects stale out-of-order tag events (design record) |
| Object Lock retention ordering | Concurrent cross-site Object Lock retention updates lacked deterministic ordering, allowing stale events to overwrite newer retention dates | Adds replication-retention-modtime and converges retention state under persistence locks (design record) |
| Delete-marker replication & version purge | Exact-version purges could create delete markers on drives missing the version, and MRF retry queues could conflate marker creation with permanent version purge | Separates delete-marker creation from permanent version purge, re-checks source state under the replication lock before sending queued marker creations, and requires write-quorum majority confirmation for missing-version purges (design record) |
Tiered versioned lifecycle expiration (#253) |
When a lifecycle Expiration rule on a versioned bucket (or versioning-suspended bucket with non-null versions) only wrote a delete marker, upstream could still delete the remote tier payload backing historical versions |
Distinguishes delete-marker insertion from permanent version expiration, keeping remote tier payloads intact whenever expiration only adds a delete marker |
SILO also isolated per-job and per-target cancellation contexts and fixed ReplicatedCount / FailedCount accounting in replication resync (Replication Resync Correctness), and added per-bucket locks plus optional field-level tombstones (MINIO_SITE_REPLICATION_METADATA_TOMBSTONES) for bucket configuration convergence (Bucket Metadata Convergence).
5. Storage Mutation, Rollback, and Multi-Pool Safety
In an erasure-coded storage engine, the happy path is straightforward; edge-case bugs hide at the intersection of slow drives, partial-write rollbacks, concurrent overwrites, and multi-pool scaling. The 20261026 release ships three groups of storage-layer safeguards:
1. Commit Error Classification and Overwrite Rollback RPC Forwarding
- Missing staging
xl.metaclassified as503 SlowDownWrite: When a slow drive or concurrent cleanup causes a stagingxl.metafile in.minio.sys/tmpto go missing during commit, SILO classifies the condition aserrFileNotFoundand returns HTTP503 SlowDownWriteso clients can retry safely instead of receiving a false404 ObjectNotFound(error classification design). - Overwrite rollback option forwarding and timeout boundaries: SILO forwards storage RPC deletion options (including the previous data directory needed for overwrite rollback) while preserving existing drive/RPC deadlines, request cancellation, object locking, read quorum, and healing rules. Note that a client-visible timeout does not mean underlying disk or RPC I/O has stopped or that the write failed to commit—late commits or delayed
UndoWritecalls can still occur after partial failures, lease loss, or network partitions (the admitted-I/O draining waits and per-drive mutation guards explored in the October maintenance draft were withdrawn indcc2f20ba; see the final maintenance boundaries).
2. Multi-Pool Locking, Two-Stage Bulk Deletion, and Migration Safety
For multi-pool deployments:
- Shared cross-pool namespace locks: Fixed pool-local lock isolation where concurrent writes, deletes, and metadata updates on different pools failed to serialize against one another.
- Two-stage multi-pool deletion (
#257): Previously, multi-poolDeleteObjectsissued parallel deletes across all pools; if the pool holding the newest version succeeded while a pool holding an older copy failed due to a drive error, the stale copy resurfaced as the current object. SILO now deletes in two stages—cleaning non-authoritative duplicate pools first and removing the authoritative copy only after stale copies are gone, while protecting referenced remote tier objects on partial failure (Multi-Pool Delete Safety). - Rebalance and decommission safeguards: Preserved object tags and revision timestamps across pool migration and prevented decommission from overwriting newer versions or dropping delete markers on the destination pool (Multi-Pool Object Consistency).
3. LIST Recovery Under Drive Disagreement (#239)
During rolling restarts with concurrent overwrites, minority drive disagreements or unresolved entries could cause ListObjects to omit readable keys. While keeping the lock-free fast path intact, SILO now confirms eligible unresolved latest-object entries on demand, distinguishes real deletions from drive read errors, and propagates terminal errors through pagination (LIST Recovery Design Record).
6. Restoring the Full Control Plane: SILO Console v2.5.1 and mcli 20261026
For day-to-day operators, the most visible difference between SILO and upstream MinIO is the administration control plane.
SILO Console v2.5.1: From a Stripped Browser Back to a Full Admin Console
In mid-2025, upstream stripped the embedded community Console down to v1.7.7—removing cluster administration, IAM, policies, lifecycle, replication, diagnostics, and monitoring panels to leave only a bare object browser—and subsequently deleted github.com/minio/console.
Building on the community restoration initiated by Georg Mangold (@gmangold), SILO shipped six major Console releases (v2.0.0 through v2.5.1), restoring the full administration suite while making the frontend smaller, faster, and telemetry-free:
| Dimension | Upstream 2025-10-15 Embedded Console (v1.7.7) |
SILO Console v2.5.1 |
|---|---|---|
| Administrative Scope | Basic bucket and object browser only; all admin panels removed | Full administration console: Overview dashboard, Buckets, Object Browser, Lifecycle, Replication, Tiering, Notifications, IAM (Users/Groups/Service Accounts/Policies with built-in policy Reset), IDP (OIDC/LDAP), KMS, Diagnostics (Health/Trace/Logs/Watch/Speedtest/Profile), and background Tasks |
| Bundle Size & Telemetry | ~10 MB bundle with external font/script dependencies and call-home hooks | < 3 MB byte-for-byte reproducible bundle, zero telemetry, zero external network dependencies, responsive light/dark themes |
| Localization | English only | Native English and Simplified Chinese toggle across UI, error messages, and documentation links |
| Metrics Integration | Legacy endpoints or removed | Native Metrics V3 integration that distinguishes real zeros from missing node data |
| Large-Bucket Browsing & Previews | Unbounded directory fetches prone to browser freezes | Cursor pagination (default 100, up to 1,000 per page), bounded 1 MiB text/Markdown/CSV/code preview, and native streaming ZIP multi-object downloads |
High-Latency Diagnostics (#63) |
Health-report downloads over high-latency links failed with WebSocket 1006 / 1011 truncation |
Fixed WebSocket close handshakes across all six diagnostic streams and repaired the madmin v3 stream decoder pre-read bug, verified under 250 ms each-way injected latency |
Console 2.5.1 also fixes group membership during status changes, OIDC group permissions, TLS-proxy session cookies, credential exports and keyboard focus. See the Console 2.5 series notes.
mcli 20261026: Honest Exit Codes and Read-Only Checksum Verification
On the client side, pgsty/mc ships as mcli (while preserving MC_* environment variables and ~/.mc / ~/.silo configuration compatibility) and fixes long-standing CLI reliability gaps:
- Read-only
mcli checksum verify: Verifies end-to-endFULL_OBJECTchecksums across buckets, prefixes, or object versions directly against the server without mutating objects or writing local files, supporting--versions,--Algo, and--json. - Nonzero exit codes on partial or permission failures:
mcli admin info --jsonnow exits nonzero when access is denied or a node reportsstatus: error(upstream exited0);mcli mirror,mcli mv,mcli retention,mcli legalhold, andmcli sqlall return nonzero exit codes on partial object failures, source-deletion errors, or permission denials;- Downloads interrupted mid-stream fail immediately rather than reporting a truncated file as complete.
- Safe
mirrordelete propagation and--dry-runrestarts: Preventedmirror --removefrom deleting destination objects when source listing fails; added--dry-runtomcli admin service restart; and honored optional persistedregionsettings in alias configurations.
The 20261026 client also isolates cached identities, drains resync JSON through terminal states, fixes rate overflow, returns nonzero for partially failed start/cancel operations, and adds batch pending output with bounded fallback when live metrics are missing. See the mcli changes and script migration notes.
7. Operations, Configuration, and Supply-Chain Delivery
Across server operations and artifact delivery, SILO made four practical changes:
- Enforced request-header timeouts and trusted-proxy boundaries:
- Upstream defined
--read-header-timeout/MINIO_READ_HEADER_TIMEOUTwithout wiring it intohttp.Server, leaving HTTP/1 connections vulnerable to slowloris-style trickle headers. SILO wired the setting into the HTTP server with a 30-second absolute HTTP/1 header deadline (design record). - Added
MINIO_API_TRUSTED_PROXIESandMINIO_IDENTITY_LDAP_STS_TRUSTED_PROXIESsoX-Forwarded-Foris never trusted blindly by default; addedCONSOLE_WS_MAX_MESSAGE_BYTESandCONSOLE_WS_MAX_DECOMPRESSED_BYTESto bound embedded Console WebSocket frames. - Added a native
silo healthchecksubcommand for shell-free distroless containers and tightenedMINIO_CONFIG_ENV_FILEparsing to reject malformed lines.
- Upstream defined
- Hardened event notification targets:
- Fixed NATS reconnect handling and JetStream async reply subjects, AMQP confirm-mode lock contention, PostgreSQL/MySQL TLS configuration loading, and preserved Kafka’s default protocol version
2.1.
- Fixed NATS reconnect handling and JetStream async reply subjects, AMQP confirm-mode lock contention, PostgreSQL/MySQL TLS configuration loading, and preserved Kafka’s default protocol version
- Permanently removed self-update and call-home:
- Removed in-place binary self-update (
MINIO_UPDATE) and allSUBNETregistration, telemetry, license checks, and phone-home endpoints. Upgrades are managed cleanly through OS packages (RPM/DEB/APK) and container images.
- Removed in-place binary self-update (
- Rebuilt a verifiable multi-architecture supply chain:
- Built all components with Go 1.27.3 (including built-in
crypto/x509distrusted-intermediate checks), UBI 9.8 and distroless container variants, staticcurl 8.23.0, and Red Hat’sRHSB-2026-012root CA blocklist. - Published Linux (
amd64/arm64/ppc64le/s390x), macOS (amd64/arm64), and Windows (amd64/arm64ZIP) archives, RPM/DEB/APK packages, and multi-arch Docker Hub images (pgsty/silo,pgsty/silo-console,pgsty/mc,pgsty/kes) backed by GPG signatures, SPDX SBOMs, and GitHub Sigstore build attestations (see Downloads).
- Built all components with Go 1.27.3 (including built-in
8. Honest Boundaries: Withdrawn Experiments and Open Limits
Maintaining storage software in production requires knowing what to roll back when an idea does not survive real capacity or failure testing. Over the past year, we implemented, benchmarked, and deliberately withdrew or closed four designs:
- Withdrew public persistent
ListMultipartUploadsdisk scanning (#79):- Goal: Upstream’s
ListMultipartUploadsreads only a node-local in-memory cache, losing visibility of incomplete uploads across restarts. In September we implemented a persistent scan across storage pools and erasure sets. - Why we rolled it back: Capacity testing showed scan latency grew linearly with prefix depth and abandoned upload count, timing out at 20,000 incomplete uploads and amplifying drive I/O. In Server 20261018 we withdrew public persistent scanning and retired the optional
strictmode, returning to the node-local cache plus exact-key lookup (see ListMultipartUploads Design and Capacity Evidence).
- Goal: Upstream’s
- Deferred strict generation read refusal and automatic cross-pool read recovery:
- Goal: When partial overwrite failures left split object generations across drives or pools, we tested refusing divergent reads or auto-recovering across pools during
GET. - Why we deferred it: Fault-injection testing showed that refusing reads after a failed partial overwrite broke MinIO’s established availability contract (where the prior readable version remains accessible). Those strict diagnostics remain gated behind the non-default
consistency_strictbuild tag while production builds preserve existing read-quorum and healing behavior.
- Goal: When partial overwrite failures left split object generations across drives or pools, we tested refusing divergent reads or auto-recovering across pools during
- Closed multi-pool overwrite affinity without merge (#245):
- Goal: In multi-pool clusters, unversioned overwrites can land on a different pool and leave stale copies on the old pool. PR
#245routed overwrites back to the object’s existing pool. - Why we closed it: When the historical pool lost write quorum due to failed drives while another pool remained healthy, forced affinity caused overwrites to fail outright—and two rounds of multi-node
m3benchmarks showed small-object overwrite latency still missed our bar (see Overwrite Pool Affinity).
- Goal: In multi-pool clusters, unversioned overwrites can land on a different pool and leave stale copies on the old pool. PR
- Removed experimental access-frequency intra-cluster tiering (
ilm access_*):- The experimental feature never met production reliability requirements and was removed in Server 20260916 (see Access-Frequency Tiering Removal).
Remaining Operational and Upgrade Boundaries
When evaluating or upgrading to SILO, keep these boundaries in mind:
- No distributed lock fencing: If a node loses its lock lease during a GC pause, network partition, or stalled drive, an already-admitted commit on that node can still land late; partial metadata updates can still briefly expose stale tags or attributes. The release retains existing timeout semantics; a returned request is not proof that underlying I/O has stopped.
- No unverified cluster-wide throughput claims: We verify hot-path microbenchmarks (for example,
silo-pkg v3.14.3reducedContainsAdminActionfrom 24 allocations and742.5 ns/opto zero allocations and5.53 ns/op), but we have not run a head-to-head multi-node benchmark between2025-10-15and2026-10-26on dedicated hardware. - Coordinated upgrades for new IAM and replication state: While on-disk
xl.metav1.3 remains compatible, features such as durable IAM revocations (siloParentRevocation) and site-replication metadata tombstones require all participating nodes to upgrade together rather than running mixed versions indefinitely or performing rolling downgrades (see the Component Matrix and IAM Upgrade Guide). - Known minor items: The repository’s Helm chart (
7.0.3) default server image tag still points toRELEASE.2026-09-16T00-00-00Z(overrideimage.taginvalues.yamlwhen deploying newer releases), and two legacy batch-lifecycle handlers in Console (batch expiration and batch transition creation) have early-return/empty-slice quirks that do not affect single-rule configuration and are queued for the next Console patch.
Closing Note
When we forked MinIO a year ago, the goal was simple: keep a production-grade open-source S3 server alive with timely CVE patches, a complete administration console, honest bug fixes, and clean binary and container distributions.
One year later—604 commits, 7 CVE patches, 18 security boundary hardenings, and dozens of root-cause write-ups in our Design Archive and Security Archive—that is the ledger of what SILO has done.
If you are running open-source MinIO, see the Migration Guide and Downloads page. If you hit a reproducible protocol, replication, or storage bug in production, open an issue at pgsty/silo.
2 - MinIO Fork, Promise Kept
Two months ago in “MinIO is Dead, Long Live MinIO,” I promised I’d keep the MinIO fork patched. The recurring objection on HN is fair: can one person actually maintain something like this? The real answer isn’t clicking fork. It’s what happens when CVEs start landing.
Between April 15 and 17, pgsty/minio shipped RELEASE.2026-04-17,
closing four CVEs and a handful of related vulnerabilities disclosed in the same window.
The scope I committed to originally was narrow: no new features, keep the supply chain running, handle reproducible bugs and security issues as they come in. This release is what it looks like when that promise gets tested.
What happened upstream
In December 2025, MinIO moved the open-source repo to maintenance mode. The README said security fixes would be “evaluated case by case.” In February 2026, the repository was archived and the landing page became “this repository is no longer maintained.”
The SECURITY.md in that same archived repo still says: “we will always provide security updates for the latest release.”
Over the past month, four high-severity and two medium-severity vulnerabilities have been disclosed against the final open-source release.
It’s been 184 days since the last upstream release. Vulnerabilities get disclosed; fixes ship only in the commercial build. The guidance for OSS users is a single line: upgrade to AIStor.
AIStor starts around $100k/year for 400 TiB — roughly S3 pricing, for software you install and operate yourself.
It’s a clean arrangement: archive the repo so there’s no obligation to patch, keep publishing CVE advisories for visibility, and route everyone who reads them toward the commercial product.
Someone still has to patch the old one.
What this release fixes
Full write-ups, CVSS arithmetic, and PoCs are in the release notes. The short version:
- CVE-2026-33322 (OIDC JWT algorithm confusion, CVSS 9.8): under certain IdP configurations, an attacker who knows the OIDC ClientSecret can mint a token claiming any identity — including
consoleAdmin— and MinIO will accept it. Vulnerable window: November 2022 through March 2026. About three and a half years. - CVE-2026-33419 (LDAP STS enumeration and brute-force): the login endpoint leaks which usernames are real, and there’s no rate limiting on the subsequent password guessing. End of the chain is an STS credential.
- CVE-2026-34204 (replication-header metadata injection): a regular PUT or COPY with certain
X-Minio-Replication-*headers can write an object into a permanently unreadable state. The data is still on disk; you just can’t read it back out. - CVE-2026-39414 (S3 Select memory exhaustion): one request, one OOM.
- GHSA-hv4r-mvr4-25vw / GHSA-9c4q-hq6p-c237: two signature-verification bypasses on the unsigned-trailer path. Anonymous or forged-signature requests can successfully write objects on certain routes.
Plus the usual dependency cleanup from go-jose, go.opentelemetry.io, and the Go 1.26.2 upgrade itself — about twenty security items in total counting transitive dependencies.

How it got fixed
I said in the earlier post that I’d rely on AI coding agents, and that’s how this round went. My role was closer to “review and decide” than “write code.”
Per-issue flow, roughly:
- Codex drafts first. Given the CVE description and relevant code paths, it produces an initial patch.
- Claude Code reviews adversarially. Picks holes from the attacker’s side.
- Back to Codex. If it agrees with Claude Code’s critique, it reworks. If not, it has to write out why. No silent overrides.
- Another round of review by Claude Code, with both sides’ reasoning on the table. Iterate until they converge.
- Tests. Codex proposes cases, Claude Code adds more, Codex runs them, Claude Code reviews the results.
- I decide. Read the diff, run the tests, merge or send it back with comments.
I didn’t write any of the code in this round. My job was to define the problem, set constraints, pick between approaches, read diffs, run tests, and merge. The GitHub log shows Vonng, Codex, and Claude Code as co-authors — that’s just who did the work.

A few things I noticed about how this runs in practice.
Two heterogeneous agents in opposition catch more than one agent alone. A single agent patching a security bug tends toward confident-sounding fixes that quietly miss a boundary condition. Having a second agent argue against the first filters out most of those.
It forces the tradeoffs into writing. When two implementations diverge, someone has to say why A over B. That exchange is the thing I can actually act on as the person deciding what to merge.
Real maintenance is patch-on-patch, not one-shot. The LDAP STS fix is a good example. The first version landed, and then we realized: successful requests shouldn’t count against the rate limit; X-Forwarded-For shouldn’t be trusted by default; the limiter should key on source IP plus normalized username, not just one. Three follow-up commits before it settled. Iterating through that by hand would have cost a lot more time.
Why this fork exists
Because I use MinIO myself.
MinIO is a production dependency for Pigsty. I need working binaries, a complete console, packages that keep shipping, and someone actually handling CVEs. That keeps the scope narrow. No new features, no turning the repo into a playground. Compatibility, supply chain, fixes when they’re needed.
— Chainguard also ships MinIO container images that track upstream’s post-archive commits, a useful option if you use their images. This fork is a different shape: source tree, RPM/DEB packages, restored console, and doesn’t depend on upstream continuing to push patches somewhere.
The fork is at about 1,300 stars on GitHub and 50,000+ pulls on Docker Hub now. Not remarkable numbers, but enough to tell me I’m not the only one who needed this fork to keep shipping.

2026-10-25 update: The maintained Docker image is now
pgsty/silo. The Docker example below uses the current name; see the migration guide.
If you’re already running OSS MinIO, migration is cheap:
- Docker: swap
minio/minioforpgsty/silo. - RPM / DEB: on GitHub Releases, or via
pig. - Source: pgsty/minio
- Docs: silo.pgsty.com
You don’t need to replace anything around it or relearn the API. In most cases, you’re just pointing a compatible binary at the same deployment. If you want a full HA production setup, Pigsty ships one for free.
Something I use broke; I’m fixing it.
What’s different in 2026 is the cost of “I’m fixing it.” With two coding agents and someone to referee between them, the maintenance load of a mid-sized Go codebase is tractable for one person in a way it wasn’t a year or two ago. That’s about it — not a grand theory about open-source resilience, just the current operating point.
If you’re running OSS MinIO, the migration is cheap and the patches are current. If another CVE drops, I’ll still be here.
3 - MinIO Is Dead, Long Live MinIO
MinIO’s open-source repo has been officially archived. No more maintenance. End of an era — but open source doesn’t die that easily.
I created a MinIO fork, restored the admin console, rebuilt the binary distribution pipeline, and brought it back to life.
2026-10-25 update: The maintained Docker image is now
pgsty/silo. The Docker links and examples below use the current name; see the migration guide.
If you’re running MinIO, swap minio/minio for pgsty/silo.
Everything else stays the same. (CVE fixed, and the console GUI is back)
The Death Certificate
On December 3, 2025, MinIO announced “maintenance mode” on GitHub. I wrote about it in MinIO Is Dead.
On February 12, 2026, MinIO updated the repo status from “maintenance mode” to “no longer maintained”, then officially archived the repository. Read-only. No PRs, no issues, no contributions accepted. A project with 60k stars and over a billion Docker pulls became a digital tombstone.

If December was the clinical death, this February commit was the death certificate.
Today (Feb 14), a widely circulated article titled How MinIO went from open source darling to cautionary tale laid out the full timeline.

Percona founder Peter Zaitsev also raised concerns about open-source infrastructure sustainability on LinkedIn. The consensus in the international community is clear:
MinIO is done.
Looking back at the timeline over the past years, this wasn’t a sudden death. It was a slow, deliberate wind-down:
| Date | Event | Nature |
|---|---|---|
| 2021-05 | Apache 2.0 → AGPL v3 | License change |
| 2022-07 | Legal action against Nutanix | License enforcement |
| 2023-03 | Legal action against Weka | License enforcement |
| 2025-05 | Admin console removed from CE | Feature restriction |
| 2025-10 | Binary/Docker distribution stopped | Supply chain cut |
| 2025-12 | Maintenance mode announced | End-of-life signal |
| 2026-02 | Repo archived, no longer maintained | End of project |
A company that raised $126M at a billion-dollar valuation spent five years methodically dismantling the open-source ecosystem it built.
But Open Source Endures
Normally this is where the story ends — a collective sigh, and everyone moves on.
But I want to tell a different story. Not an obituary — a resurrection.
MinIO Inc. can archive a repo, but they can’t archive the rights that the AGPL grants to the community.
Ironically, AGPL was MinIO’s own choice. They switched from Apache 2.0 to AGPL to use it as leverage in their disputes with Nutanix and Weka — keeping the “open source” label while adding enforcement teeth. But open-source licenses cut both ways — the same license now guarantees the community’s right to fork.
Once code is released under AGPL, the license is irrevocable. You can set a repo to read-only, but you can’t claw back a granted license. That’s the beauty of open-source licensing by design: a company can abandon a project, but it can’t take the code with it.
So — MinIO is dead, but MinIO can live again.
That said, forking is the easy part. Anyone can click the Fork button. The real question isn’t “can we fork it” but “can someone actually maintain it as a production component?”
Why would I do that?
I didn’t set out to take this on. But after MinIO entered maintenance mode, I waited a couple of weeks for someone in the community to step up.
But I didn’t find one. So I did it myself.
Some background: I maintain Pigsty — a batteries-included PostgreSQL distribution with 460+ extensions, cross-built for 14 Linux distros. I also maintain build pipelines for 290 PG extensions, several PG forks, and dozens of Go Projects (Victoria, Prometheus, etc.) packaging across all major platforms. Adding one more to the pipeline was a piece of cake.
I’m not new to MinIO either. Back in 2018, we ran an internal MinIO fork at TanTan (back when it was still Apache 2.0), managing ~25 PB of data — one of the earliest and largest MinIO deployments in China at the time.
More importantly, MinIO is an optional module in Pigsty. Many users run it as the default backup repository for PostgreSQL in production. We did consider several alternatives, but none were a drop-in replacement for MinIO-based workflows.
We use MinIO ourselves, so keeping the supply chain alive was not optional — it had to be done. As early as December 2025, when MinIO announced maintenance mode, I had already built CVE-patched binaries and switched to them.
What We’ve Done
As of today, three things.
1. Restored the Admin Console
This was the change that frustrated the community the most.
In May 2025, MinIO stripped the full admin console from the community edition, leaving behind a bare-bones object browser. User management, bucket policies, access control, lifecycle management — all gone overnight. Want them back? Pay for the enterprise edition. (~$100,000)
We brought it back.

The ironic part: this didn’t even require reverse engineering.
You just revert the minio/console submodule to the previous version.
They swapped a dependency version to replace the full console with a stripped-down one. The code was always there.
We put it back.
2. Rebuilt Binary Distribution
In October 2025, MinIO stopped distributing pre-built binaries and Docker images,
leaving only source code. “Use go install to build it yourself” — that was their answer.
For the vast majority of users, the value of open-source software isn’t just a copy of the source — supply chain stability is what matters. You need a stable artifact you can put in a Dockerfile, an Ansible playbook, or a CI/CD pipeline — not a requirement to install a Go compiler before every deployment.
We rebuilt the distribution:
- Docker Images
pgsty/silois live on Docker Hub.docker pull pgsty/siloand you’re good.- RPM / DEB Packages
- Built for major Linux distributions, matching the original package specs.
- CI/CD Pipeline
- Fully automated build workflows on GitHub, ensuring ongoing supply chain stability.
If you’re using Docker, just swap minio/minio for pgsty/silo.
For native Linux installs, grab RPM/DEB packages from the GitHub Release page. You can also use pig (the PG extension package manager) for easy installation, or configure the pigsty-infra APT/DNF repo to install from it:
Just works as usual.
3. Restored Community Edition Docs
MinIO’s official documentation was also at risk — links had started redirecting to their commercial product, AIStor.
We forked minio/docs, fixed broken links, restored removed console documentation, and deployed it as the SILO documentation site.
The docs use the same CC Attribution 4.0 license as the original, with necessary maintenance.

Commitments
Some things worth stating up front to set expectations.
No New Features — Just Supply Chain Continuity
MinIO as an S3-compatible object store is already feature-complete. It’s a finished software. It doesn’t need more bells and whistles — it needs a stable, reliable, continuously available build. (I already have PostgreSQL for these, so I don’t need something like S3 table or S3 vector. A stable S3 core is all I need)
What we’re doing: making sure you can get a working, complete MinIO binary, with the admin console included and CVE fixed. RPM, DEB, Docker images — built automatically via CI/CD, drop-in compatible with your existing minio. We keep the existing minio naming and behavior where legally and technically feasible.
This Is a Production Build, Not an Archive
We run these builds ourselves and have been dogfooding them in production for three months. If something breaks, we detect it early and patch it quickly.
I build this primarily for Pigsty and our own usage, but I hope it helps others too.
I’m willing to Track CVEs and Fix Bugs
If you run into issues, feel free to report them at pgsty/minio.
I’ll do my best to fix these — but please don’t treat this as a commercial SLA.
Given that AI coding tools have made bug fixing dramatically cheaper, and that we’re explicitly not adding any new features, I believe the maintenance workload is manageable. (how often do you see one?)
Trademark Is Tricky, But We’ll Cross That Bridge When We Come to It
Disclaimer
Trademark Notice: MinIO® is a registered trademark of MinIO, Inc. This project (pgsty/minio) is an independently maintained community fork under the AGPL license. It has no affiliation with, endorsement by, or connection to MinIO, Inc. Use of “MinIO” in this post refers solely to the open-source software project itself and implies no commercial association.
AGPLv3 gives us clear rights to fork and distribute, but trademark law is a separate domain. We’ve marked this clearly everywhere as an independent community-maintained build.
If MinIO Inc. raises trademark concerns, we’ll cooperate and rename (probably something like silo or stow).
Until then, we think descriptive use of the original name in an AGPL fork is reasonable — and renaming all the minio references doesn’t serve users.
AI Changed the Game
You might ask: can one person really maintain this?
It’s 2026. Things are different now.
AI coding tools are changing the economics of open-source maintenance.
With tools like Claude Code & Codex, the cost of locating and fixing bugs in a complex Go project has dropped by more than an order of magnitude. What used to require a dedicated team to maintain a complex infra project can now be handled by one experienced engineer with an AI copilot.
Maintaining a MinIO build without adding new features is a manageable task. The key requirement is testing and validation. and we already have that scenario, which lets us verify compatibility, reliability, and security in practice.
Consider: Elon cut X/Twitter’s engineering team down to ~30 people and the system still runs. Maintaining a MinIO fork without new features is considerably less daunting
Just Fork It
MinIO Inc. can archive a GitHub repo, but they can’t archive the demand behind 60k stars, or the dependency graph behind a billion Docker pulls. That demand doesn’t disappear — it just finds its way out.
HashiCorp’s Terraform got forked into OpenTofu, and it’s doing fine. MinIO’s situation is actually more favorable —
AGPL is more permissive for forks than BSL, with no legal gray area for community forks.
A company can abandon a project, but open-source licenses are specifically designed so the code can’t die.
Fork is the most powerful spell in open source. When a company decides to shut the door, the community only needs two words:
Fork it.
Reference
- MinIO Is Dead
- MinIO Is Dead, Are There Alternatives?
- From AGPL to Apache: Reflections on Pigsty’s License Change
- MinIO: Promise made, Promise kept
4 - MinIO Is Dead. Which Next?
MinIO announced maintenance mode two days ago. I ranted in “MinIO Is Dead” and immediately got flooded with “so what now?”
The usual suspects: Ceph, RustFS, SeaweedFS, Garage. I packaged all of them for Linux (RPM/DEB) and ran them through the grinder.
Short version: there’s no perfect substitute. Ceph is powerful but overkill; SeaweedFS rocks tiny files but needs an external metadata DB; Garage is cute but too barebones; RustFS targets the MinIO niche but is still alpha.
Quick scan of the field
MinIO is the open-source S3 clone. If all you need is basic object CRUD, any S3-compatible store works. But parity with MinIO means more than APIs—it’s about reliability, operability, tooling, documentation, SOPs. Replacing it cleanly is hard.
Ignoring commercial clouds, here’s the OSS menu:
- Ceph – arguably the best choice for enterprises, but brutally complex. Most folks don’t need block + file + object in one, and it requires extras like Podmon. MinIO’s single binary spoiled us.
- SeaweedFS – optimized for oceans of small files; O(1) disk seeks make it absurdly fast there. But it relies on an external metadata store. If you want a general-purpose object store, that dependency is annoying.
- Garage – built by Deuxfleurs with NGI funding. Delightfully light (10 MB), great for self-hosters and edge nodes. But S3 compatibility is thin: no versioning, no cross-region replication, no IAM. Enterprises will laugh.
- RustFS – the only project explicitly chasing “drop-in MinIO,” but it’s still alpha.
RustFS vs. MinIO
RustFS looked the most promising, so I wired it into Pigsty as a MinIO replacement. Most logic carried over, but a few differences popped up:
- Certificates must follow specific naming rules.
- Health checks differ from MinIO’s endpoints.
mc admindoesn’t work; you can’t push fine-grained IAM policies. That’s a deal-breaker for many teams.
It ran, but I’m not shipping alpha software into production, so I shelved the branch. I’ll revisit when RustFS hits GA.
Will RustFS repeat MinIO’s mistakes?
RustFS has potential, but I worry it’ll retrace MinIO’s path. I asked the AI big three (GPT‑5 Pro, Claude 4 Opus, Gemini 3 Pro) to audit the project. Gemini leveled some serious accusations; Claude corroborated.
The red flags match MinIO’s history: Apache 2.0 license + copyright assignment CLA + single commercial gatekeeper. With that risk profile, I’m downgrading RustFS from “optimistic” to “cautious wait-and-see.”
So what now?
Pigsty bundles MinIO as an optional module for PostgreSQL backups or as an on-prem S3 for apps like Supabase. After surveying the alternatives, I’m not eager to swap it out. I might add a pgBackRest-native backup server option, but ripping out MinIO today feels premature.
Best plan: stay on the latest MinIO release, lock the version, isolate it on the network, and wait a few months. Maybe the community forks it; maybe RustFS matures. Adjust when reality changes.
RustFS still has a golden window to seize MinIO’s niche with a safer, community-friendly fork. That window is measured in months, not years.
If you stick with MinIO
Use the latest build, not the April 22, 2025 edition with the GUI. There’s a serious CVE in the interim:
- CVE-2025-62506 – privilege escalation via session-policy bypass (HIGH). Low-privilege users can mint new accounts and escalate.
In a locked-down intranet the risk is manageable, but you still want the fix, which landed in the 2025‑10‑15 release. MinIO pulled the prebuilt binaries starting with that version, offering source only. Annoying, but it’s Go—go build and you’re done. I forked MinIO, ran their packager, and produced RPM/DEBs for 2025‑12‑03 so I’m not deploying vulnerable bits: https://github.com/pgsty/minio

Security patches still need humans. MinIO claims they’ll fix critical issues, but if the community wants a maintained fork, now’s the moment. Start from 2025‑04‑22, cherry-pick critical bug/security fixes, and keep a community LTS alive.
MinIO is “done” software. It doesn’t need the latest S3 gimmick (Vector/Table); it needs steady bugfixes. That’s perfect for a community branch. Plenty of storage vendors rely on MinIO; maintaining a fork beats writing a new object store from scratch.
2026-02-14 Update: MinIO’s official repo has been fully archived and is no longer maintained. Besides, I’ve personally maintained an oss fork of minio:
pgsty/minio/ Docs: https://silo.pgsty.com. Which based on the last upstream version 2025-12-03 with restored console capabilities.
5 - MinIO is Dead
December 3, 2025 was a day to mark in open-source software history. MinIO’s team updated the project status on GitHub, announcing the MinIO open-source project was entering “maintenance mode.” This basically declared the death of MinIO as an open-source project.
MinIO the company has finally completed its transformation from a dragon-slaying hero into the very dragon it once sought to slay.

From Dragon-Slayer to Dragon
Democratization Era (2014–2019): The Apache of Object Storage
MinIO was founded in 2014 with a highly idealistic vision – to be “the Apache of object storage.” In an era dominated by AWS S3, MinIO’s ultra-lightweight design (a single static binary) and 100% S3 API compatibility quickly won developers’ hearts.
During this phase, MinIO was licensed under the liberal Apache 2.0 license, encouraging developers to integrate it into all kinds of applications. Its core pitch: “turn any hardware into AWS S3.” This open strategy was wildly successful. MinIO claimed its Docker image had been pulled over 1 billion times, making it the world’s most widely deployed object storage service. At this point, MinIO was a darling of the cloud-native stack – the default storage backend in many Kubernetes setups.
License Weaponization (2019–2025): The AGPL War
The first major crack in community relations appeared around 2019–2021. MinIO announced it was changing its core license from Apache 2.0 to GNU AGPLv3.
The official explanation was that this move aimed to prevent cloud providers (like AWS, Azure) from “freeloading” the code and repackaging it as proprietary services — a common defensive tactic in open source. During this period, MinIO shifted from being a community guardian to an aggressive defender of its IP. In 2022, MinIO publicly accused Nutanix Objects of violating its license and revoked Nutanix’s right to use MinIO; in 2023, MinIO sued high-performance filesystem vendor Weka on similar grounds. These legal actions, though legally contentious, sent a clear signal: MinIO no longer welcomed commercial use without paying up. This set the legal and psychological stage for the full lockdown that would come in 2025.
Control Plane Neutered (May 2025)
In May 2025, MinIO decided to strip the MinIO Console out of the community edition. The console was a critical GUI for bucket management, IAM, monitoring, and audit logging. After this removal, the open-source MinIO was left with only a basic “object browser” GUI – essentially just a file viewer/downloader.
Meanwhile, key admin features like policy management, site replication configuration, and lifecycle management were moved entirely into the commercial enterprise edition. This change downgraded the open-source MinIO from a full-featured storage management system into a mere data-plane component, robbing it of the control-plane capabilities needed to run as a standalone product in production.
Cutting Off Binary Distribution (Oct 2025)
On October 15, 2025 – right as a critical security vulnerability (CVE-2025-10-15T17-29-55Z / GHSA-jjjj-jwhf-8rgr) was disclosed – MinIO stopped publishing updated Docker images to Docker Hub and Quay.io. The timing of this move was highly strategic. By cutting off binaries during a major security incident, MinIO effectively used security as a bargaining chip.
This decision directly broke the automated deployment pipelines for countless users. Helm charts, Ansible playbooks, and Terraform scripts expecting minio/minio (or Bitnami’s minio) image suddenly failed to find updates.
Auto-scaling groups trying to pull new nodes hung due to missing images. For teams without a Go build environment or an internal container registry, MinIO instantly became unusable.
Maintenance Mode (Dec 2025)
On December 3, 2025, MinIO, Inc. officially updated its channels and GitHub repo to announce that the open-source project is now in “maintenance mode.” The README stated that there will be no further feature additions or improvements, issues and PRs will no longer be reviewed, and even critical security fixes would be provided “as appropriate.” No more RPM/DEB packages or Docker images will be released. Essentially, anyone needing updates or support is advised to switch to the commercial AIStor product.

Technical Impact: Damage to the Open-Source Ecosystem
MinIO’s move to maintenance mode dealt an immediate and far-reaching blow to many tech stacks.
Broken CI/CD Pipelines and an Automation Crisis
Thousands of Helm charts, Ansible playbooks, and Terraform scripts depend on the minio/minio (or Bitnami’s minio) container image.
With official images no longer published, third-party packagers like Bitnami — who can’t get a stable upstream release — also had to stop updates.
- Cascade effect: Deployments in fresh environments started failing outright. Auto-scaling groups, upon launching new instances, would hang or error out when the MinIO image couldn’t be pulled.
- Cost of fixes: Companies now have to rewrite their deployment scripts to point to a self-hosted image, and set up internal build pipelines to compile and package MinIO from source.
Security Vacuum: CVE Patches Go Private
The most lethal consequence of halting binary distribution is delayed security patches. In the October 2025 incident, for example, MinIO effectively withheld the patched binaries for the vulnerability.
- Risk exposure: Companies without dedicated security teams are forced to keep running older, vulnerable versions with known critical flaws.
- Compliance nightmare: For organizations under PCI-DSS, HIPAA, SOC2, etc., not being able to obtain vendor-signed security updates is a compliance disaster. Lacking official patches, they technically fall out of compliance.
Exponentially Higher Ops Complexity
Removing the UI wasn’t just a hit to user experience – it increased operational burden.
Tasks that used to be a few clicks in the Console (configuring bucket policies, setting user permissions) now require ops engineers to master the mc CLI or hand-craft complex JSON policy docs.
This raises the skill floor and makes MinIO far less friendly as a lightweight internal tool.
Underlying Reasons: Pressure from Capital and Commercialization
The driving force behind MinIO’s decisions is the logic of venture capital. By 2025, MinIO had raised a total of $126 million in funding. The most significant was a $103 million Series B in January 2022 led by Intel Capital, SoftBank Vision Fund II, and General Catalyst, which crowned MinIO a unicorn (valued over $1 billion).
In VC terms, a $1B valuation means the company must show a clear path to IPO — typically demanding $100M+ in Annual Recurring Revenue (ARR) and rapid growth. In Feb 2025, MinIO announced its ARR had grown 149% over the past two years businesswire.com. Impressive growth, but to live up to a sky-high valuation, organic conversion alone wasn’t enough.
Cutting off the free open-source offering is the most direct way to force a huge user base into paid customers.
In 2025, MinIO underwent a full rebrand and launched “MinIO AIStor,” styling itself as “the data backbone for enterprise AI.” Management recognized that general-purpose object storage (for backups, file servers, etc.) was a red-ocean market with thin margins, whereas generative AI’s appetite for high-throughput data (the exascale AI era) promised the next big surge. By tuning its product for AI workloads and focusing on Fortune 500 enterprises linkedin.com, MinIO essentially decided to cut loose its low-value open-source user base. The move to maintenance mode signaled MinIO’s official pivot from a broad open-source project into a vertical, high-end AI software vendor.
MinIO isn’t a garage hobby project by a few geeks anymore; it’s a company that took $126M in VC and is valued at over $1B. Backed by Intel Capital and SoftBank, once you take that money, your boss is no longer the users — it’s the investors. And what do investors want? ARR, growth, IPO. You tell them, “We have a billion Docker pulls!” and they’ll ask, “How many dimes did those pulls pay us?”
The reality is brutal. To the VCs, those small businesses and individual devs using free MinIO are low-value assets. They open issues and ask for support — consuming expensive engineer time, bandwidth, and servers — yet will never convert to paying customers. MinIO’s leadership knows their real cash cows are the Fortune 500 firms doing generative AI. The ones training GPT models or running self-driving pipelines need AIStor, ultra-high performance, and 24/7 enterprise SLAs.
So flipping the project into “maintenance mode” is essentially an asset carve-out. MinIO is cutting away the “dead weight” (free users) and concentrating on the milkable “cash cows” (enterprise AI clients). In business strategy this is called focus. To the investors, it’s being responsible. But from the perspective of open source, it’s simply betrayal.
Personal Reflections
I started using MinIO around 2018 (back when it was Apache-licensed). We built a few multi-petabyte object storage clusters for videos, images, backups — probably one of the largest MinIO deployments in China at the time. I wrote deployment/monitoring playbooks for MinIO (still open-sourced in Pigsty).
As an open-source startup founder, I can understand the motivation behind these moves. But as an open-source contributor and user — I also know many folks right now have one phrase in their minds: “I have never seen such shamelessness.”
An open-source license isn’t a shackle, but it is a social contract. Developers contribute code, users contribute testing, feedback, and reputation; together, they make a project successful. MinIO enjoyed a decade of community goodwill and parlayed the bragging rights of “#1 in global downloads” into venture funding. Then it turned around and told the very users who propped it up: “You free-riders, get lost.” This kind of move breaks the fundamental trust that open source is built on.
This “bait and switch” tactic is even more nauseating than a crypto rug pull. A rug pull only takes your money — MinIO is pulling the rug out from under the tech stacks of thousands of companies. Adopting a technology isn’t just picking up a binary; it’s buying into an ecosystem and a design philosophy. They got everyone onboard, let the switching costs pile up sky-high, and then suddenly kicked away the ladder. In fact, as open-source expert Tison thoroughly discussed in his article The Bait-and-Switch Open-Source Strategy, the core issue with this model is deception.
MinIO betrayed the community, so the community may abandon it as well. Alternatives like Garage, SeaweedFS, or the new RustFS are ready to step in.
If I have to sum up my feelings, I’d borrow a line from The Hitchhiker’s Guide to the Galaxy:
—— “So long, and thanks for all the fish.”
2026-02-14 Update: MinIO’s official repo has been fully archived and is no longer maintained. Besides, I’ve personally maintained an oss fork of minio:
pgsty/minio/ Docs: https://silo.pgsty.com. Which based on the last upstream version 2025-12-03 with restored console capabilities.




