* fix(ci): include pagination regression in full E2E selection * fix(deps): replace yanked yoke-derive release * fix(scanner): expose pause backlog replica diagnostics (#8258) * fix(scanner): expose pause backlog replica diagnostics Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * fix(connect): stabilize runtime profile lease cancellation Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(connect): tolerate delayed schedule startup in CI Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(e2e): retry quota reads during usage warmup Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * fix(ecstore): avoid meta-bucket incarnation self-deadlock Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * fix(test): use persisted incarnation in heal fixture Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: zhi22915 <qiuzgang@gmail.com> * fix(usage): reconcile stale counters after lifecycle expiration (#8108) * fix(usage): reconcile stale counters after lifecycle expiration * fix(usage): account lifecycle expiry during continuous writes * test(usage): run lifecycle usage scenarios on one scanner store * test(usage): use a Windows-representable pre-mutation offset * fix(usage): harden expiry accounting recovery and quota checks Borrow expiry receipt bucket names and avoid allocating a map key on cache hits. Cover cancelled receipts, durable snapshot recovery, and legacy quota admission after scanner confirmation. Use representable timestamp offsets in the quota regression. Refs rustfs/backlog#2689 Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(usage): recover stale persisted counts through the scanner Seed incorrect complete usage for empty and retained-object buckets, then run the real scanner and publication consumer without further object mutations. Verify durable and admin usage over two cycles instead of writing a corrected snapshot in the test. Refs rustfs/backlog#2689 Refs rustfs/backlog#2691 Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(e2e): bound delimiter pagination fixture concurrency The 120-second smoke timeout expired after 1018 of 1200 serial fixture PUTs, before LIST ran. Prepare the same objects with at most eight concurrent requests and await every PUT. Retain the timeout and strengthen exact prefix, KeyCount, empty Contents, and continuation-token assertions with phase diagnostics. Refs rustfs/backlog#2689 Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(upgrade): establish a persisted previous-release baseline Seed the pinned previous-release cluster and restart it once with its data intact before replacing any node. Require every old writer to pass the strict readiness probe and preserve the seed through both mixed phases and the final current cluster. Keep InternalError fail-fast behavior and all existing compatibility deadlines and assertions. Refs rustfs/backlog#2689 Refs rustfs/backlog#2384 Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(ecstore): bound cancellation metadata persistence waits Use the system-bucket incarnation boundary now supplied by main PR #8268. Bound the three cancellation waits that previously hung during pool.bin persistence, retaining their remote-generation, target-cohort, and durable-state assertions. Refs rustfs/backlog#2697 Refs rustfs/backlog#2689 Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: Chris <anzhengchao@gmail.com> Co-authored-by: Hauser <housemecn@gmail.com> Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * test(e2e): retain startup and shutdown failure diagnostics * fix(test): supply CPU workload for sampler regression * fix(ci): locate security chain scripts in the workspace * fix(usage): recover historical counters with generation fencing (#8273) * fix(usage): recover historical counters during continued writes Use newer converged scanner snapshots to reconcile stale absolute usage baselines while preserving concurrent mutation and expiry receipt fences. Cover durable publication, admin and quota reads, and legacy generations. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * refactor(usage): fence snapshots and move preserved cache entries Apply the cached scanner generation floor before every reconciliation path and retain it even when an older snapshot happens to match core counts. Move preserved usage entries instead of cloning their histogram maps under the cache lock, retaining expiry receipt identity and cancellation fences. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * test(scanner): verify checkpoint takeover and repair dispatch (#8275) * test(scanner): cover checkpoint handoff and repair dispatch Drive runtime budget expiry, partial-cycle persistence, leadership claims, and stale checkpoint rejection between real disk-backed fixture scans. Verify that a metadata repair beyond the first bounded prefix is saved in the scanner ledger and dispatched by the MRF consumer. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * ci: isolate scanner fixtures and refresh full e2e membership Reserve nextest capacity for the real-disk scanner publication and MRF admission fixtures. Bind both platform membership checks to the reviewed pagination deadline test added on main. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * refactor(scanner): consolidate checkpoint fixture lifecycle Keep one durable control store across timeout and leadership transitions, and inject generation advancement into the shared checkpoint scenario. Check the actual saved metadata path so late-write rejection also proves that existing checkpoint bytes remain intact. Centralize MRF fixture isolation and reuse nextest process isolation when the startup environment already satisfies the test contract. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * fix(obs): distinguish allocator counters from live memory (#8274) * fix(obs): distinguish allocator counters from live memory Preserve count/counter semantics and mark requested-byte attribution unavailable when live statistics or sampling are missing. Document sustained multipart memory diagnosis. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * refactor(obs): parse allocator statistics from one node Resolve each statistic before interpreting its shape, avoiding unsupported-field tree scans and mixing data across wrapper scopes. Preserve unavailable-statistics policy and add precedence regressions. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * test(ecstore): isolate late parity recovery from metadata hedges Use the existing object-scoped hedge timer barrier in exact-count recovery fixtures. Preserve payload and total-read assertions and verify that the omitted parity disk is read only during late refresh. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * fix(usage): combine identical snapshot retention branches * fix(test): await HTTP sender readiness in Top RPC fixture * [release/1.0.1] Gate multipart copy through write admission (#8284) Gate multipart copy through write admission Make UploadPartCopy acquire the shared foreground write admission permit before lifecycle locks or source readers so server-side multipart copy cannot bypass the same backpressure used by UploadPart. Document the shared queue semantics and add focused coverage for saturation, cancellation, lock ordering, and disabled admission. Co-authored-by: zhi22915 <qiuzgang@gmail.com> * Gate multipart copy through write admission (#8283) Make UploadPartCopy acquire the shared foreground write admission permit before lifecycle locks or source readers so server-side multipart copy cannot bypass the same backpressure used by UploadPart. Document the shared queue semantics and add focused coverage for saturation, cancellation, lock ordering, and disabled admission. Co-authored-by: zhi22915 <qiuzgang@gmail.com> * fix: add UploadPart OOM validation guardrails (#8287) * docs(release): validate candidates on release branch * fix(scanner): validate checkpoints against global cycle fence (#8278) ## Related Issues Related to rustfs/backlog#2701. ## Summary of Changes Route scanner checkpoint cycle and leader validation through the global store while retaining the owning set for cache persistence, CAS revisions and publication admission. ## Verification Two independent final-diff source reviews found no issues across correctness, concurrency and durability, test coverage, compatibility, performance and simplicity on head `8b8fe51d092090b053f552ae283960e2e306be33`. Root approval `5373624714` is bound to that exact head. Regression tests cover real two-pool routing, stale fences, post-save rejection and CAS conflicts; their reported local execution belongs to the PR author, not this merge operation. Current required CI remains pending, and this authorized admin squash does not establish CI or runtime acceptance. ## Impact Restores checkpoint progress when global cycle and leader state differ from a set-scoped view. No format, retry, timeout, assertion or scanner-policy changes are introduced by this diff. The three prior main scanner failures remain unproved repaired. ## Additional Notes Full validation must run on the resulting exact main revision. Reverting this patch restores the earlier set-scoped fence lookup and its checkpoint rejection behavior. * fix(ci): restore E2E membership and pagination timeouts (#8281) * ci: locate the auto-testing checkout for lanes that run evidence from a subdirectory (#8279) ## Related Issues Follow-up to #8229. ## Summary of Changes Locate the private auto-testing checkout from the lane root or the workspace root so the nested security checkout can record functional-chain evidence. ## Verification The exact PR headb66129ab9fpassed one mechanical correctness and simplicity review, nine real-Git layout and provenance checks, and sixteen existing evidence/envelope tests. The baseline sibling layout failed with git exit 128; the corrected layout succeeded while revision mismatches and missing checkouts stayed rejected. Current PR checks are completed with successful or skipped conclusions, including the aggregate. ## Impact Both lane and private-script revision checks remain intact. No time limits, assertions, production behavior, or evidence validation requirements change. The synthetic layout checks do not execute the actual scheduled security suite; integrated main CI and release acceptance remain separate gates. ## Additional Notes Approved review 5374559393 is bound to the exact head above. Reverting the single-file change restores the previous checkout lookup. * fix: add UploadPart OOM validation guardrails Add a Docker validation harness for backlog#2704 so the ordinary UploadPart low-concurrency memory workload can be reproduced with comparable case metadata, process/cgroup sampling, TLS and metrics toggles, cache-env controls, and write reclaim/direct-write experiments. Warn when operators set the unrecognized RUSTFS_OBJECT_CACHE_* variables that appeared in the reporter compose file. The variables are reported but remain ignored, so startup does not silently change object data cache behavior. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: overtrue <anzhengchao@gmail.com> Co-authored-by: AL <allan.bednarowski@gmail.com> Co-authored-by: hector <42570491+majinghe@users.noreply.github.com> Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * fix(scanner): pass fence store to checkpoint fixture * fix(s3): queue bucket operations and restore strict Clippy checks (#8290) * fix(s3): queue concurrent bucket creation and deletion Keep eight active bucket transactions and bound admission waiting to 128 requests and 30 seconds. Preserve detached transaction ownership and return Retry-After with overload responses. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * fix(ecstore): restore strict Clippy compatibility on Rust 1.99 Use try_update without changing atomic ordering or overflow behavior. Keep recursive storage futures boxed once at each frame and remove the redundant async-recursion macro, including its non-recursive SQL planner use. Remove needless closure borrows and orphaned dependency entries. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * chore: refresh dependencies and atomic update APIs Update workspace dependencies and the lockfile. Replace deprecated atomic fetch_update aliases with try_update while preserving closures and memory ordering. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * improve * fix(scanner): diagnose and verify pause backlog recovery (#8293) * fix(scanner): diagnose and verify pause backlog recovery Expose the retained replica snapshot and claimed membership in abnormal admin status responses. Keep diagnostics off metrics updates and verify single-pool recovery and conflicting-proof preservation across 24 sets. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> * refactor(scanner): move replica snapshots into diagnostics Consume the terminal admin read snapshot in a single state match and move membership, revision, and error buffers into the response. Verify buffer handoff and the unchanged JSON contract without altering ledger authority. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> --------- Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> * fix(heal): wait for held legacy responsibility in replay test * ci: remove Docker Hub description sync * fix: emit NextPartNumberMarker only when ListParts is truncated ListPartsInfo.next_part_number_marker was a non-optional usize that defaulted to 0 and was only assigned when the response was truncated. The S3 serializer then emitted it unconditionally as Some(0), causing AWS SDK paginators to loop infinitely on part_number_marker=0 instead of terminating. Change the field to Option<usize> (None by default) and set it only inside the is_truncated branch. The S3 output layer now uses .and_then() so NextPartNumberMarker is absent when IsTruncated=false, matching AWS S3 behavior. Fixes #8208 (cherry picked from commit44de803a38) * fix(s3): honor sparse ListParts markers and verify termination Resume part listings at the first part above the numeric marker, even when that marker is absent. Use binary search over the sorted part numbers and retain the existing exact-tail empty-slice path. Add storage, XML, and real AWS SDK paginator regressions for empty and terminal pages, sparse markers, and multipart completion integrity. Co-Authored-By: heihutu <heihutu@gmail.com> Co-Authored-By: zhi22915 <qiuzgang@gmail.com> (cherry picked from commit673031eea1) * fix(storage): publish delete rollback backups atomically Stage rollback metadata outside the rollback directory and publish it only after the full write succeeds. A short write must not leave a backup that quorum rollback can rename over acknowledged version history. Add an isolated real short-write regression and register the backported ListParts SDK test in the smoke and Linux full inventories. * test(e2e): register paginator regression in Darwin inventory * fix(release): install yq before Helm template checks * chore(release): align installation references for 1.0.1 --------- Co-authored-by: Hauser <housemecn@gmail.com> Co-authored-by: zhi22915 <qiuzgang@gmail.com> Co-authored-by: Peder Bergan <pederbe@users.noreply.github.com> Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: AL <allan.bednarowski@gmail.com> Co-authored-by: hector <42570491+majinghe@users.noreply.github.com> Co-authored-by: Chapman <touch65536@gmail.com>
RustFS Config - Configuration Management
Configuration management and validation module for RustFS distributed object storage
📖 Documentation
· 🐛 Bug Reports
· 💬 Discussions
📖 Overview
RustFS Config provides configuration management and validation capabilities for the RustFS distributed object storage system. For the complete RustFS experience, please visit the main RustFS repository.
✨ Features
- Multi-format configuration support (TOML, YAML, JSON, ENV)
- Environment variable integration and override
- Configuration validation and type safety
- Hot-reload capabilities for dynamic updates
- Default value management and fallbacks
- Secure credential handling and encryption
📚 Documentation
For comprehensive documentation, examples, and usage guides, please visit the main RustFS repository.
Environment Variable Naming Conventions
RustFS uses a flat naming style for top-level configuration: environment variables are RUSTFS_* without nested module segments.
Examples:
RUSTFS_REGIONRUSTFS_ADDRESSRUSTFS_VOLUMESRUSTFS_LICENSERUSTFS_LICENSE_PUBLIC_KEY
Current guidance:
- Prefer module-specific names only when they are not top-level product configuration.
- Renamed variables must keep backward-compatible aliases until before beta.
- Alias usage must emit deprecation warnings and be treated as transitional only.
- Deprecated example:
RUSTFS_ENABLE_SCANNER->RUSTFS_SCANNER_ENABLEDRUSTFS_ENABLE_HEAL->RUSTFS_HEAL_ENABLEDRUSTFS_DATA_SCANNER_START_DELAY_SECS->RUSTFS_SCANNER_START_DELAY_SECS
License environment variables
RUSTFS_LICENSEcontains the signed license token.RUSTFS_LICENSE_PUBLIC_KEYcontains the RSA public key used to verify signed license tokens.
CORS environment variables
RUSTFS_CORS_ALLOWED_ORIGINSdefaults to empty, so the S3 endpoint emits no generic CORS headers unless configured. Set*for wildcard origins without credentials, or a comma-separated allow-list for credentialed explicit origins.RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINSdefaults to*for the console service.
Console URL prefix
RUSTFS_CONSOLE_PREFIX changes the embedded console URL prefix. The default is
/rustfs/console. For example, RUSTFS_CONSOLE_PREFIX=/console serves the UI at
http://localhost:9001/console/. Nested prefixes such as /management/console
are supported; one trailing slash is removed. Restart the server after changing it.
The prefix must be a non-root absolute path of at most 256 bytes, with nonempty
segments containing only ASCII letters, digits, -, _, ., or ~. Dot
segments, encoded characters, and overlaps with reserved admin, RPC, health,
profiling, browser entry, and icon routes are rejected at startup. / is not supported.
Choose a prefix that does not collide with S3 bucket paths.
The console routes, embedded frontend asset URLs, browser redirects, and OIDC
console redirects use this prefix. Admin API paths and the identity provider's
/rustfs/admin/v3/oidc/callback/... URL remain unchanged. RUSTFS_CONSOLE_ADDRESS
continues to control only the listening address and port. The server adapts bundled
console asset references from their build-time base path to the runtime prefix.
OEM builds can set RUSTFS_CONSOLE_BASE_PATH when compiling RustFS to embed a
different default, such as /nuofans/console. Build the bundled console with the
same NEXT_PUBLIC_BASE_PATH. An unset or empty build variable retains
/rustfs/console. The build path must satisfy the validation rules above and must
not have a trailing slash.
At startup, RUSTFS_CONSOLE_PREFIX takes precedence over the compiled default.
Changing RUSTFS_CONSOLE_BASE_PATH when starting an existing binary has no effect;
rebuild both components to change the embedded default. If a runtime prefix is
configured, asset adaptation uses the compiled base path as its source, including
when restoring /rustfs/console for a custom OEM build.
Browser redirect environment variables
RUSTFS_BROWSER_REDIRECT_URLsets the externally reachable browser origin used for OIDC callback, console success redirect, and logout fallback URLs. Configure it to the public scheme and authority without a path, for examplehttps://console.example.com. In load-balancer deployments, keep OIDC authorize and callback requests on the same backend node because the in-flight OIDCstateis local to the RustFS node.
S3 API environment variables
RUSTFS_API_OBJECT_MAX_VERSIONScaps the number of retained versions for a single object. It defaults to9223372036854775807, matching MinIO's practical-unlimited default. Set a positive integer to enforce a lower per-object metadata bound.MINIO_API_OBJECT_MAX_VERSIONSis accepted as a compatibility alias when the canonical RustFS variable is not set.
Distributed endpoint locality
RUSTFS_LOCAL_ENDPOINT_HOSTidentifies this server's host in a distributedRUSTFS_VOLUMEStopology without resolving every peer during startup. Set it to exactly one host, without a scheme, port, or path. It is accepted only for orchestrated URL topologies and must match at least one endpoint on the RustFS server port; invalid or unmatched values fail startup. Leave it unset to retain DNS-based locality discovery.
Scanner environment aliases
RUSTFS_SCANNER_SPEED(canonical, also acceptsMINIO_SCANNER_SPEED)RUSTFS_SCANNER_DELAY(canonical)RUSTFS_SCANNER_MAX_WAIT_SECS(canonical)RUSTFS_SCANNER_CYCLE(canonical, also acceptsMINIO_SCANNER_CYCLE)RUSTFS_SCANNER_START_DELAY_SECS(canonical)RUSTFS_DATA_SCANNER_START_DELAY_SECS(deprecated alias for compatibility)RUSTFS_SCANNER_IDLE_MODE(canonical)RUSTFS_SCANNER_CACHE_SAVE_TIMEOUT_SECS(canonical)RUSTFS_SCANNER_CYCLE_MAX_DURATION_SECS(canonical)RUSTFS_SCANNER_CYCLE_MAX_OBJECTS(canonical)RUSTFS_SCANNER_CYCLE_MAX_DIRECTORIES(canonical)
Scanner cycle budget controls:
- When
RUSTFS_SCANNER_CYCLE_MAX_DURATION_SECSis unset, the finite default is 1800 seconds (30 minutes), matching the scanner benchmark guidance. - An explicit
0preserves the compatibility behavior of an unbounded runtime budget. Object and directory budgets likewise remain unbounded when explicitly set to0. - A timed-out cycle cancels cooperative scanner work, then fences its leader epoch before releasing the lease. An uncooperative I/O operation is dropped after the bounded shutdown window; its cursor is not claimed to be durable and the scanner reports
recovery-requiredwhen the worker cannot stop cooperatively, the cycle state was not confirmed durable, or epoch fencing cannot be persisted.
Mmap read environment aliases
RUSTFS_OBJECT_MMAP_READ_ENABLE(canonical)RUSTFS_OBJECT_ZERO_COPY_ENABLE(deprecated alias for compatibility)
Health compatibility switches
RUSTFS_HEALTH_ENDPOINT_ENABLE- controls canonical
/health,/health/live, and/health/readyendpoint exposure.
- controls canonical
RUSTFS_HEALTH_MINIMAL_RESPONSE_ENABLE- enables minimal payload mode for GET health responses (
status,readyonly).
- enables minimal payload mode for GET health responses (
RUSTFS_HEALTH_READINESS_CACHE_TTL_MS- TTL for readiness cache evaluation.
RUSTFS_HEALTH_OBJECT_PROGRESS_ENABLE- withdraws readiness when bounded object read/write stages stop completing while requests remain active.
- default is
true.
RUSTFS_HEALTH_OBJECT_PROGRESS_TIMEOUT_MS- maximum time without completion in a bounded object stage before readiness is withdrawn.
- default is
30000;0uses the default. - the effective value is at least 5 seconds longer than
RUSTFS_OBJECT_LOCK_ACQUIRE_TIMEOUT. - this readiness SLO is independent of disk read/write failure deadlines and may withdraw traffic before those deadlines expire.
RUSTFS_HEALTH_COMPAT_BUSY_CHECK_ENABLE- enables busy protection behavior for health probes.
- default is
false.
RUSTFS_HEALTH_COMPAT_BUSY_MAX_ACTIVE_REQUESTS- max active HTTP requests; health probes return
429when active requests reach or exceed this value. 0disables thresholding even if busy protection is enabled.
- max active HTTP requests; health probes return
RUSTFS_HEALTH_COMPAT_KMS_READY_CHECK_ENABLE- enables KMS readiness enforcement for
/health/ready. - default is
false.
- enables KMS readiness enforcement for
Object lock admission environment variables
RUSTFS_PUT_COMMIT_NAMESPACE_LOCK_ACQUIRE_TIMEOUT_MS- experimental same-object PUT commit namespace-lock admission budget.
- default is
0, which disables this override and keepsRUSTFS_OBJECT_LOCK_ACQUIRE_TIMEOUTbehavior. - when set, only
put_object_commitwrite-lock acquisition is bounded by this millisecond budget; other namespace lock users keep the global object-lock timeout. - timeout returns S3
SlowDown, so clients should use normal SDK retry handling. - this is not a fdatasync or group-commit switch. Track fdatasync batching separately with
rustfs_s3_put_object_rename_fdatasync_batch_files.
Foreground write admission environment variables
Large direct PutObject requests, multipart UploadPart requests, and
server-side multipart UploadPartCopy requests share one per-process permit
pool that bounds concurrent body ingest and storage writes. Small direct PUTs
stay on the legacy path.
RUSTFS_PUT_LARGE_FOREGROUND_ADMISSION_ENABLE- enables the default-on pool;
falsekeeps only the soft request counter. - default is
true.
- enables the default-on pool;
RUSTFS_PUT_LARGE_FOREGROUND_ADMISSION_LIMIT- a positive value is an exact request-count limit shared by all gated writes.
- default is
0: derive half ofRUSTFS_OBJECT_MAX_CONCURRENT_DISK_READS, clamped to32, as large-write slots. Each slot has eight units. A gated direct PUT or unknown-size multipart part uses eight units; known-size parts use one unit per 8 MiB, rounded up, with a minimum of one and maximum of eight. - stock settings therefore share 256 units across at most 32 large/unknown writes or 256 parts of up to 8 MiB. Mixed sizes consume the same budget. Admitted known parts of up to 64 MiB total at most 2 GiB of declared payload; larger streaming writes and queued bodies are separate. This is not a bound on total process or kernel memory.
- admission snapshots report allocated or reserved units in
activeand the unit budget inlimitunder automatic sizing. Explicit and strict limits still report request-count permits.
RUSTFS_PUT_LARGE_FOREGROUND_ADMISSION_MIN_SIZE_BYTES- smallest direct
PutObjectthat takes a permit; unknown-size requests always do. - default is
33554432(32 MiB).
- smallest direct
RUSTFS_PUT_LARGE_FOREGROUND_ADMISSION_WAIT_TIMEOUT_MS- how long a direct
PutObjectwaits for a permit before returning S3SlowDown. - default is
250.
- how long a direct
RUSTFS_PUT_MULTIPART_FOREGROUND_ADMISSION_MIN_SIZE_BYTES- smallest
UploadPartthat takes a permit;0gates every part. - default is
0.
- smallest
RUSTFS_PUT_MULTIPART_FOREGROUND_ADMISSION_WAIT_TIMEOUT_MS- how long an
UploadPartorUploadPartCopywaits in the bounded queue for a permit before returning S3SlowDown;0rejects immediately when the pool is full. - default is
10000. Parts wait before body ingest or source-object reads, so SDK-default clients that send every part of an upload concurrently drain through the pool instead of failing on a full pool. - RustFS does not read the request body while a part is queued, so the client's socket write stalls for the whole wait and whatever timeout the client or an intermediary has configured competes with this value.
UploadPartCopywaits before taking bucket lifecycle locks or opening source readers, and uses the unknown-size weight because the authoritative copy length is available only after source metadata and range validation. Keep the wait with margin below the shortest client/proxy timeout in use (botocore applies its 60 sconnect_timeoutto the body write; the AWS SDK for Java v2 has a 30 s socket write timeout; reverse proxies add their own body timeouts); a wait that outlives the client timeout surfaces as a dropped connection instead ofSlowDown.
- how long an
RUSTFS_PUT_MULTIPART_FOREGROUND_ADMISSION_MAX_PENDING- maximum
UploadPartandUploadPartCopyrequests waiting for a permit at once; parts beyond it returnSlowDownwithout waiting. - default is
0, which derives 16 times the large-write slot count, or the explicit request-count limit (512 at stock settings). Automatic subdivision does not enlarge this queue. - each queued HTTP/1 part holds whatever unread body the client already pushed into the connection's kernel receive buffer (an HTTP/2 part holds up to its flow-control window in process memory). Autotuned receive buffers can remain large on reused connections; queue depth does not imply a fixed per-connection memory cost.
- maximum
RUSTFS_PUT_FOREGROUND_ADMISSION_ENABLE,RUSTFS_PUT_FOREGROUND_ADMISSION_LIMIT,RUSTFS_PUT_FOREGROUND_ADMISSION_WAIT_TIMEOUT_MS- experimental strict gate that applies to every foreground write regardless of size and replaces the pool above when enabled.
- default is disabled; enabling it with limit
0disables foreground write admission entirely.
HTTP listener socket environment variables
RUSTFS_HTTP_SOCKET_RECV_BUFFER_BYTES- fixed
SO_RCVBUFfor the API listener, inherited by every accepted socket;0leaves the receive buffer to kernel autotuning. - default is
0. A fixed buffer disables receive autotuning. Linux doubles the requested value for socket-memory accounting, subject to kernel limits; that capacity is not a measurement of queued payload or allocated memory. - with autotuning the receive ceiling is controlled by the kernel (
net.ipv4.tcp_rmemon Linux); its defaults vary with kernel version and memory. A connection can retain a buffer enlarged by previous requests while its next request is queued. Tune the kernel ceiling first, and set this variable only on kernels without receive-buffer autotuning (illumos/Solaris) or where the sysctl cannot be changed. - the send buffer remains fixed at 4 MiB; this setting only controls the receive side.
- fixed
Remote tier timeout environment variables
RUSTFS_TIER_REMOTE_CONNECT_TIMEOUT_SECS- remote tier TCP connect timeout.
- default is
10. - must be positive; zero fails tier client initialization, while an invalid integer is logged and falls back to the default.
RUSTFS_TIER_REMOTE_REQUEST_TIMEOUT_SECS- remote tier request timeout through response headers.
- default is
86400so large transition uploads keep a production-safe budget. - must be positive; zero fails tier client initialization, while an invalid integer is logged and falls back to the default. Very large values are accepted and act as a correspondingly long budget.
RUSTFS_TIER_REMOTE_RESPONSE_BODY_IDLE_TIMEOUT_SECS- maximum idle time between remote tier response-body chunks.
- default is
60; the timer resets only when non-empty body data keeps progressing. - must be positive; zero fails tier client initialization, while an invalid integer is logged and falls back to the default.
Drive timeout environment variables
RUSTFS_DRIVE_METADATA_TIMEOUT_SECSRUSTFS_DRIVE_DISK_INFO_TIMEOUT_SECSRUSTFS_DRIVE_LIST_DIR_TIMEOUT_SECSRUSTFS_DRIVE_WALKDIR_TIMEOUT_SECSRUSTFS_DRIVE_WALKDIR_STALL_TIMEOUT_SECS
Legacy compatibility fallback:
RUSTFS_DRIVE_MAX_TIMEOUT_DURATIONThis legacy variable is treated as a deprecated fallback for the operation-specific drive timeout variables above when a canonical variable is unset.
Drive timeout health-action policy:
RUSTFS_DRIVE_TIMEOUT_HEALTH_ACTIONmark_failure(default): timeout marks failure and may transition drive runtime state.ignore_scanner: timeout does not mark failure for scanner-sensitive operations (walk_dir,read_metadata,list_dir,disk_info).
Drive timeout profile preset:
RUSTFS_DRIVE_TIMEOUT_PROFILEdefault(default): keep current timeout defaults.high_latency: use 60s default timeout for scanner-sensitive operations when no operation-specific override is set (read_metadata,disk_info,list_dir,walk_dir,walk_dir_stall, and object-capacity scan base/maximum budgets).
- Precedence:
- Explicit per-operation timeout env (
RUSTFS_DRIVE_*_TIMEOUT_SECS) takes highest precedence. - Explicit object-capacity timeout env (
RUSTFS_CAPACITY_STAT_TIMEOUT,RUSTFS_CAPACITY_MAX_TIMEOUT) takes precedence for capacity scans. - Then
RUSTFS_DRIVE_MAX_TIMEOUT_DURATIONlegacy fallback. - Then the profile-derived default (
defaultorhigh_latency).
- Explicit per-operation timeout env (
Admin peer probe timeout
RUSTFS_ADMIN_PEER_PROBE_TIMEOUT_SECS- total per-peer budget for the
server_info/storage_infoadmin probe round;server_infomay reconnect once andstorage_inforemains a single attempt. - default is
10seconds, preserving the previous two-attempt worst-case budget. - values must be positive;
0or an invalid value falls back to the default, and values above60are clamped to60. - the setting is read by the aggregating node only; it does not change the internode RPC wire contract. Any retry shares one round deadline rather than receiving a fresh timeout.
- total per-peer budget for the
Startup filesystem boundary policy
RUSTFS_UNSUPPORTED_FS_POLICYcontrols startup behavior when RustFS detects local endpoint filesystems that are outside the supported production boundary.warn(default): log warning and continue startup.fail: abort startup with an error.
RustFS production guidance remains direct-attached local POSIX filesystems. Network-mounted filesystems (for example nfs, cifs, smb2, and fuse.*) are treated as unsupported by this startup guard.
📄 License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
