Description
I am using rc 0.1.31 to mirror objects between two RustFS S3 endpoints:
RustFS source (remote NTFS) → RustFS destination (local NTFS)
The problem appears to be related to how rc mirror performs S3-to-S3 copies rather than to the underlying filesystem.
Observed behavior
I initially ran:
time rc mirror --overwrite --remove --json \
remoto/archive/2026/07 \
local/archive/2026/07
Result:
{
"source": "remoto/archive/2026/07",
"target": "local/archive/2026/07",
"copied": 764,
"removed": 0,
"skipped": 0,
"errors": 0,
"dry_run": false
}
The operation took approximately 30 minutes.
Running the exact same command again, without any changes on the source, still caused all 764 objects to be copied again.
A dry run confirmed:
{
"copied": 764,
"removed": 0,
"skipped": 0
}
ETag difference
For example, one object had:
Source
Size: 21375369 bytes
ETag: 513cf08fa7a370c31e6cee7beb120163-2
Date: 2026-08-04 22:11:52 UTC
Destination after rc mirror
Size: 21375369 bytes
ETag: 53d0b16993c80d285b6e681ef17ef6b3-1
Date: 2026-08-11 13:28:51 UTC
The content size is identical, but the ETag is different.
This causes the next rc mirror invocation to consider the object changed and copy it again.
Important comparison with mc --preserve
I then used mc cp --preserve on a smaller subset of the same S3-to-S3 data.
After that, the same object reported:
Source
Size: 21375369 bytes
ETag: 513cf08fa7a370c31e6cee7beb120163-2
Date: 2026-08-04 22:11:52 UTC
Destination
Size: 21375369 bytes
ETag: 513cf08fa7a370c31e6cee7beb120163-2
Date: 2026-08-11 14:17:36 UTC
Notice that the Date/mtime is still different, but the ETag is identical.
I then ran:
rc mirror --overwrite --remove --json \
remoto/archive/2026/07/20260726/D7500 \
local/archive/2026/07/20260726/D7500
and got:
{
"copied": 0,
"removed": 0,
"skipped": 14,
"errors": 0,
"dry_run": false
}
The operation took only:
This strongly indicates that rc mirror uses the ETag (rather than the object modification date) as an important part of its equality check.
Expected behavior
For an S3-to-S3 mirror, if the source object is copied without changing its content, I would expect the destination object to retain an identity that allows subsequent mirror operations to recognize it as unchanged.
Ideally:
source ETag == destination ETag
after a successful mirror operation, when the destination object contains exactly the same object data.
Otherwise, every subsequent rc mirror operation unnecessarily transfers the entire object again.
Why this matters
My use case is a RustFS server acting as a continuously updated mirror of another RustFS server.
The current behavior turns an incremental mirror into a full re-transfer.
After copying the same objects with mc --preserve, subsequent rc mirror correctly skips them.
Therefore, preserving object identity/ETag during S3-to-S3 mirroring would make a very significant difference for this use case.
Environment
rc version: 0.1.31
Source: RustFS S3 (rustfs 1.0.0-rc.1)
Source filesystem: NTFS3
Destination: RustFS S3 (rustfs 1.0.0-rc.1)
Destination filesystem: NTFS3
Transfer type: S3-to-S3
Description
I am using
rc 0.1.31to mirror objects between two RustFS S3 endpoints:The problem appears to be related to how
rc mirrorperforms S3-to-S3 copies rather than to the underlying filesystem.Observed behavior
I initially ran:
time rc mirror --overwrite --remove --json \ remoto/archive/2026/07 \ local/archive/2026/07Result:
{ "source": "remoto/archive/2026/07", "target": "local/archive/2026/07", "copied": 764, "removed": 0, "skipped": 0, "errors": 0, "dry_run": false }The operation took approximately 30 minutes.
Running the exact same command again, without any changes on the source, still caused all 764 objects to be copied again.
A dry run confirmed:
{ "copied": 764, "removed": 0, "skipped": 0 }ETag difference
For example, one object had:
Source
Destination after
rc mirrorThe content size is identical, but the ETag is different.
This causes the next
rc mirrorinvocation to consider the object changed and copy it again.Important comparison with
mc --preserveI then used
mc cp --preserveon a smaller subset of the same S3-to-S3 data.After that, the same object reported:
Source
Destination
Notice that the
Date/mtime is still different, but the ETag is identical.I then ran:
and got:
{ "copied": 0, "removed": 0, "skipped": 14, "errors": 0, "dry_run": false }The operation took only:
This strongly indicates that
rc mirroruses the ETag (rather than the object modification date) as an important part of its equality check.Expected behavior
For an S3-to-S3 mirror, if the source object is copied without changing its content, I would expect the destination object to retain an identity that allows subsequent mirror operations to recognize it as unchanged.
Ideally:
after a successful mirror operation, when the destination object contains exactly the same object data.
Otherwise, every subsequent
rc mirroroperation unnecessarily transfers the entire object again.Why this matters
My use case is a RustFS server acting as a continuously updated mirror of another RustFS server.
The current behavior turns an incremental mirror into a full re-transfer.
After copying the same objects with
mc --preserve, subsequentrc mirrorcorrectly skips them.Therefore, preserving object identity/ETag during S3-to-S3 mirroring would make a very significant difference for this use case.
Environment