Skip to content

mcli 20261109: Data Safety and Automation Fixes

mcli 20261109: safer removal and moves, correct multipart downloads, reliable failure reporting, metadata handling, and batch status.

mcli 20261109 is released. Tag: RELEASE.2026-11-09T00-00-00Z; package version: 20261109000000.0.0; source: e1d4cc5abfe0. These notes describe changes since 20261026.

This is a standalone mcli maintenance release. It does not replace the client embedded in an existing Server or Console build. The maintained and release-tested server is PGSTY SILO; compatibility with upstream MinIO and other S3-compatible services remains best effort.

Removal, moves and downloads

  • Dry runs stay read-only. rm --purge --dry-run previews the requested prefix without deleting it. Namespace removal protection applies to every command-line target and each stdin target; adding another argument no longer bypasses --dangerous.
  • Each copy or move uses its own source alias. Multi-source operations no longer reuse the first alias when reading or deleting later objects.
  • Known self-moves are rejected before copying or deleting the source. This includes resolved object URLs, normalized filesystem paths, symlinks and hardlinks. The endpoint guard also rejects the same bucket/key across endpoints with the same scheme and port when their IP addresses overlap, including --resolve mappings.
  • Multipart od downloads read the requested sequence. Downloads no longer repeat the last part, and opened readers are closed on success or failure. Invalid operands, zero part sizes, negative sizes and arithmetic overflow are rejected before changing the target; empty copies no longer produce invalid rate output.

The move guard is conservative: distinct virtual hosts on a shared IP and port can be refused. Establish that the stores are independent before copying, verifying and deleting explicitly; matching bytes through two aliases does not prove independence. Different IPs, ports, proxy routing, virtual-host addressing or changing DNS can conceal a shared backend. Use consistent endpoint URLs for aliases to the same store.

For endpoints reached through HTTP_PROXY or HTTPS_PROXY, a failed local DNS lookup leaves the address unknown rather than rejecting a move that the proxy can carry out. Proxy selection follows the transport’s rules, including NO_PROXY. Known self-moves are still rejected; an unresolved direct endpoint still fails.

Changes for scripts

Partial failures and continued work

Copy/move source-preparation failures, removal permission or WORM errors, and failed IAM or bucket metadata imports now return exit status 1, retaining their error details. These paths could previously report success.

cp and mv continue processing independent sources after a preparation failure, including later command-line arguments. A partially failed mv may therefore have moved and deleted other sources successfully. Successful operations are not rolled back. Check the final exit status and error records before proceeding with a dependent job.

IAM import falls back to the legacy API only when the server explicitly returns NotImplemented or XMinioAdminVersionMismatch. Other HTTP, transport and response-decoding failures do not trigger a second import.

JSON progress

Per-object cp --json and mv --json start records contain cumulative prepared counts and bytes in totalCount and totalSize, in dispatch order. They grow as source listing proceeds; they are not the final workload or a denominator for completion percentage. A start record does not confirm a completed transfer. Inspect the final exit status, error records and final byte summary.

Copy counters are race-free, and cancellation drains workers while retaining bounded streaming queues.

Object tags and attributes

Explicit --tags now applies to server-side and streaming copies and moves, including with --preserve. An explicit empty value clears tags.

Malformed --attr fails cp and mv before any transfer instead of silently discarding all requested attributes. Empty entries are ignored by cp, mv, mirror and pipe, so trailing and repeated semicolons are accepted:

mcli cp --attr 'owner=alice;;team=ops;' report.txt ALIAS/BUCKET/report.txt

A nonempty entry without =, an unterminated quote, or input containing no key/value entry, such as ;, still fails. Semicolons inside quoted values remain part of the value.

Generated upload commands

share upload now quotes complete arguments with POSIX single quotes and uses --form-string for literal policy fields. After replacing placeholders with correctly quoted values, execute the result in a POSIX shell. If the generated command is stored in upload, use sh -c "$upload"; invoking $upload directly only splits words and does not interpret the embedded quotes. On Windows, use Git Bash or WSL rather than cmd.exe.

Batch observation and diagnostics

Batch status exposes paused and complete-with-skips states, pause reasons and skip counters. Complete live details, including explicit zeros, take precedence; saved details are refreshed periodically and at completion. detailsUnavailable identifies terminal results whose full details could not be confirmed.

Observation continues for healthy running or paused jobs after saved-status polls. Live counters are preserved, saved terminal results are reported promptly, and stale terminal snapshots after a metrics disconnect are rejected.

A successful query of a complete, complete-with-skips or failed batch job still exits 0. Scripts must inspect the job state and skip counters; command success does not mean the job succeeded. Paused jobs are not terminal, and extended details require a server that supplies them.

Diagnostic fixes also cover heal progress through EiB, the first drive I/O sample as a baseline rather than an interval, and fractional site speed-test durations.

Dependencies

Component Selection
Go 1.27.3, unchanged
silo-pkg/v3 v3.16.0, up from v3.15.2
Upstream minio-go/v7 v7.4.2-0.20261025165926-320af050c445, unchanged
golang.org/x/net v0.62.0
golang.org/x/crypto v0.58.1-0.20261009181718-2f1f834330b2
klauspost/cpuid/v2 / YAML v3 v2.4.2 / v3.0.6
tidwall/gjson v1.20.1

The SDK and x/crypto selections are pinned upstream commits, not corresponding final version tags. This version adopts the networking and crypto security floors and the silo-pkg 3.16.0 updates. The gjson update preserves UTF-8 characters following malformed emoji input. Existing systemd, terminal-width and tablewriter compatibility selections remain in place.

Container configuration

The container definition pre-creates /.mc with sticky writable permissions for non-root UIDs that have no passwd entry and receive HOME=/. Root retains /root/.mc; --config-dir and MC_CONFIG_DIR still take precedence. Persistent deployments and containers with a read-only root filesystem should mount a writable configuration directory.

The published image supports linux/amd64 and linux/arm64. The version tag and latest point to the same multi-architecture image:

docker pull pgsty/mc:RELEASE.2026-11-09T00-00-00Z
docker run --rm pgsty/mc:RELEASE.2026-11-09T00-00-00Z --version

Artifacts and verification

The GitHub Release provides 19 assets: Linux/macOS tar.gz and Windows ZIP archives for amd64/arm64, Linux RPM, DEB and APK packages for both architectures, and checksums. All asset digests, 11 build-provenance attestations and both RPM signatures were verified. The signed tag identifies the exact source that passed Go tests, cross-compilation, vulnerability checks and the release-pipeline gate.

Release acceptance covered package installation and removal, container configuration, and data-safety, metadata, import and automation checks against SILO. The container workflow used the verified Linux release binaries and ran both architecture images before publishing the version and latest manifests. See Downloads for platform-specific artifacts.

Full changelog · Changes since 20261026 · Compatibility notes