About this article: AI-assisted writing, reviewed against the cited sources. This is source research, not a lab validation of the procedures. Check the stated versions and your own recovery requirements before making changes.
Object storage is an attractive place for a copy of a Linux server's files. It can provide off-server storage, but capacity costs, request rates, retention and recovery time still require planning. A sync tool copies a folder into a bucket and the bucket looks, in most browsers and tools, like the same folder.
It is not the same folder. An S3 bucket stores objects, each with a name, some bytes and a small amount of metadata. Everything a Linux file system records beyond that (owner, group, permission bits, access control lists, extended attributes, symbolic and hard links, empty directories, most timestamps) must be represented deliberately, for example in supported object metadata, a manifest or an archive. A plain object-per-file transfer does not automatically preserve it. When it is carried, it survives only as long as the same tool, or a compatible one, reads it back.
This guide works through what Amazon S3 itself keeps for an object, what the widely used rclone tool adds on top, and what that means for a restore. It complements our earlier article on verifying that a backup was delivered to S3 or SFTP, which is about proving the bytes arrived. This one is about whether the file around those bytes can be rebuilt.
Why it matters
Consider an object-to-file restore onto a fresh server or into a clean folder. If the copy kept only names and contents, the restored files belong to whoever ran the restore, carry default permissions and carry the restore date. Three practical problems follow.
Services do not start. Daemons that check ownership and permissions on their keys, sockets or data folders refuse to run when those are wrong. SSH host keys, database data directories and web server certificates are common examples.
Security is weakened. Files that were private to one account may come back readable by others, or the reverse may stop a service reading what it needs.
Links and structure change. A symbolic link that pointed at a shared folder may come back as a full copy of the target, as a small text file, or not at all. An empty folder an application expects may be missing.
None of these is visible while the bucket simply holds the data. They show up during the restore, which is the worst time to find them.
How S3 stores a "file"
There are no folders
The Amazon S3 user guide is direct about the model: "The Amazon S3 data model is a flat structure: You create a bucket, and the bucket stores objects. There is no hierarchy of subbuckets or subfolders." What looks like a path is part of the object's name. AWS explains that "Object key names include any prefixes (known as folders in the console)", and that the prefix, delimiter and name together count toward a "maximum length of 1,024 bytes".
Because folders are only prefixes, a folder with nothing in it has no object to represent it. The console works around this by creating a "zero-byte object with the folder prefix and delimiter value as the key". Sync tools handle empty directories in their own ways, and the rclone overview notes of empty-directory support that "Most Object/Bucket-based remotes do not support this." The practical consequence is that empty directories in the source are a known gap to check, not something to assume.
Names are UTF-8 strings with a few traps
A key is "a sequence of Unicode characters encoded in UTF-8", and "Object key names are case sensitive." That matches Linux well, with three cautions.
First, Linux file names are bytes, not necessarily valid UTF-8. The rclone local backend documentation says that "If an invalid (non-UTF8) filename is read, the invalid characters will be replaced with a quoted representation of the invalid bytes." The transferred representation can differ from the original bytes. A byte-exact round trip depends on the tool's encoding and decoding path; test it rather than assuming loss or preservation.
Second, path segments made only of dots are risky. AWS warns that such keys "can cause unexpected behavior when processed by applications, SDKs, or tools that interpret these as relative path references", and states "we recommend avoiding period-only path segments in object key names." rclone encodes the names . and .. to look-alike characters for the same reason.
Third, consecutive slashes cause trouble with at least one common tool. The rclone S3 documentation says that when it meets such a key "it will normalize the path to use a single slash", which can produce "object not found" errors. Linux paths rarely contain doubled slashes as stored names, but keys written by other tools may.
The metadata S3 keeps for you
The AWS metadata reference describes system-defined object metadata. The entries that matter for a file copy are these.
- Last-Modified. AWS defines it as "The object creation date or the last modified date, whichever is the latest", and lists it as one the user cannot modify. This is a service-side object timestamp, not the source file mtime. AWS specifically says that for multipart uploads the object creation date is initiation of the upload; it is not proof of upload completion.
- Content-Length, the size in bytes, also not user-modifiable.
- ETag. For objects not uploaded in parts and either unencrypted or using SSE-S3, "the ETag is an MD5 digest of the data". For other objects it is not, so the ETag cannot be relied on as a content hash in general (our reading of the same entry and of the rclone note below).
- Checksum headers. S3 stores checksum metadata for supported integrity workflows; the integrity guide notes that "The CRC64NVME checksum algorithm is the default checksum algorithm used for checksum calculations."
- Version ID, when versioning is enabled.
Nothing in that list records a Linux owner, group, mode or file timestamp.
User-defined metadata, and its limits
S3 also lets the uploader attach user-defined metadata as name-value pairs, sent as x-amz-meta- headers. This is where a sync tool can carry Linux attributes. The limits are tight and worth knowing:
- Size: "Within the PUT request header, the user-defined metadata is limited to 2 KB in size."
- Case: "Amazon S3 stores user-defined metadata keys in lowercase."
- Characters: "If some metadata contains unprintable characters, it is not returned." Non-ASCII values are encoded and decoded under RFC 2047.
- Immutability: "After you upload the object, you can't modify this user-defined metadata. The only way to modify this metadata is to make a copy of the object and set the metadata."
The limit is per object and includes the UTF-8 bytes of metadata keys and values. A short security label may fit, while a large attribute set may not. Capacity is separate from support: the tool still needs to capture and reconstruct each required namespace. Verify that excess metadata is rejected visibly or preserved in an explicit alternative representation, never silently truncated.
What rclone carries, and how
rclone is the documented example here; other tools need their own metadata contract.
Without the metadata option
By default, "Normally rclone only preserves the modification time and the content (MIME) type where possible." For S3, the modification time is not the Last-Modified header. rclone stores it separately: "The modified time is stored as metadata on the object as X-Amz-Meta-Mtime as floating point since the epoch, accurate to 1 ns."
That has two consequences. Another tool reading the same bucket will see Last-Modified, the upload time, unless it knows about rclone's key. And because "the metadata isn't returned in object listings", reading every file's modification time costs an extra request per object. rclone's own cost-saving advice includes a mode in which "Modification time becomes the time the object was uploaded", with the warning that "Files created with timestamps in the past will be missed by the sync." That is a trade worth understanding before it is chosen for a backup.
With --metadata
rclone "supports preserving all the available metadata on files and directories when using the --metadata or -M flag", though "Exactly what metadata is supported and what that support means depends on the backend."
On the Linux side, the local backend lists the system metadata it can read and write: atime, btime, gid, mode, mtime, rdev and uid. It adds that "User metadata is stored as extended attributes" in the user.* namespace. The project states its goal plainly: "you can copy a local file with file attributes and xattrs from local disk to s3 and back again losslessly."
Read carefully, that goal has edges:
- Only the user namespace of extended attributes is described as user metadata. Attributes in other namespaces, including the ones that hold POSIX ACLs and SELinux labels, are not listed, so they should be assumed lost unless tested. Validate ACLs and security labels separately from user-namespace attributes.
- Everything carried must fit in the S3 user-metadata limit above.
- On the S3 side, btime is "read from Last-Modified header" and marked read-only, so do not assume the value projected from S3 is the source file's birth time. If historical birth time matters, verify a separate retained representation and the destination's ability to use it.
- Ownership is numeric. A uid of 500 on the source means whoever is 500 on the restore server. Verify the intended identity mapping before access is enabled.
Restoring ownership is deliberately cautious
The local backend documentation warns that the owner and mode values "come from the source remote which may not be trusted, so restoring metadata as root from an untrusted source can change file ownership and is not recommended." A non-root user "keeps its own uid and sets the gid only to a group it is a member of, as rsync does." And "The setuid, setgid and sticky bits are not restored by default", which needs a separate option.
For a restore plan this means two things. Applying privileged metadata needs adequate authority and a trusted source, but that alone does not establish full system-file fidelity. And special permission bits, which some system binaries and shared folders depend on, will not come back unless that option is chosen deliberately.
Metadata syncs once
One sentence in the rclone documentation is easy to miss: "Rclone only supports a one-time sync of metadata." It continues: "If the metadata subsequently changes on the source object without changing the object itself then it won't be synced to the destination object."
A file whose permissions or owner were changed after the first copy, with no change to its contents, keeps the old values in the bucket (our reading of that statement). Over months, the bucket's idea of who owns what can drift away from the server's. Permission fixes, ownership changes after a migration and security hardening are exactly the kind of change that touches metadata without touching contents.
Links and special files
The local backend says "Normally rclone will ignore symlinks or junction points". Two options change that: one follows links and copies what they point at; the other stores each link "as text files, with a .rclonelink suffix in the remote storage". The first can turn a small link into a large duplicate, or loop; the second keeps the link but reconstruction requires the matching rclone option or another explicitly compatible decoder.
The cited rclone pages discuss hard links being broken when local files are replaced, but do not describe preserving hard-link identity in object storage. S3 has no concept of two names for one object, so each name is expected to become a separate full object and to come back as a separate file. Do not rely on hard-link or sparse-allocation preservation without verifying the archive or metadata representation. Device files, sockets and named pipes are likewise not ordinary content; the rdev entry suggests rclone records device numbers, but how special files are handled was not confirmed.
Integrity: is it the same data?
Metadata aside, the data itself needs a check. AWS describes server-side validation on upload: "S3 then independently calculates a checksum value of the object on the server-side, and validates it with the provided value before storing the object and checksum value."
The ETag is often used as an MD5 of the data, but only holds for some uploads. rclone notes that for multipart uploads or certain encryption modes "the ETag header is no longer the MD5 sum of the data", so it adds its own X-Amz-Meta-Md5chksum value. A verification that compares ETags with local MD5 sums will therefore report false mismatches on large files unless it accounts for this.
Our delivery verification article covers checking that every object arrived intact. The point here is narrower: integrity of the data does not imply integrity of the metadata.
Versioning can retain object history
A sync to a bucket mirrors the source. If a file is deleted or encrypted by ransomware on the server, the next sync may faithfully copy that change. In a versioning-enabled bucket, an ordinary deletion without a specific version ID creates a marker, while overwrites retain earlier versions. The versioning guide summarises this: "if you delete an object, Amazon S3 inserts a delete marker instead of removing the object permanently", and "If you overwrite an object, it results in a new object version in the bucket."
Three facts from the AWS guide shape a plan:
- "By default, S3 Versioning is disabled on buckets, and you must explicitly enable it."
- "Each version of an object is the entire object; it is not just a diff from the previous version." Storage grows with every changed file.
- "After you version-enable a bucket, it can never return to an unversioned state." It can only be suspended.
Versioning interacts with the metadata rules above. Because user metadata can only be changed by writing a new copy, a tool that updates metadata creates new versions too (our reading of the immutability rule together with the versioning description). rclone also says that when a modification time must be updated it "will attempt to perform a server side copy", which in a versioned bucket is another version.
Versioning is not immutable retention. Version-specific deletion and lifecycle expiry can remove history, so assess those permissions and rules separately. Object Lock is a different retention control and is outside this article's scope. A set of individually retained versions also needs a coherent recovery point for related application files.
A worked example
Illustration only, not a measured case.
A small business copies /srv/shared and /etc from a Linux file server to an S3-compatible bucket each night with a sync tool, using rclone's default content-transfer behaviour, without metadata preservation. The server fails and a new one is built.
The shared folder is restored. Every file now belongs to the account that ran the restore, with default permissions. Modification times are correct, because the tool stored them in its own metadata. Suppose the destination defaults allow staff to open the files, but the original group-based policy is not reproduced, and two empty project folders that a scanner application writes into are missing.
The /etc restore is worse. A symbolic link that pointed one configuration to another was skipped. If destination creation permissions are too broad, private keys may be readable by unintended local accounts; isolate the restore until effective access has been validated. A service may also reject a key file whose permissions are too broad.
With supported metadata preservation and adequate restore privileges, owner and group numbers and modes could also travel. They would match only if the new server used the same uid and gid numbers. Any permission changes made after each file's first upload would be missing, because metadata is synced once. This documented metadata path does not establish preservation of the original ACLs (our reading of the documentation above).
The lesson from the example: for system configuration and anything with meaningful ownership, put the files into an archive format that records Linux metadata, then store the archive in object storage. A supported backup format or manifest can also represent these dependencies. Choose based on tested recovery behaviour rather than object storage alone.
A planning checklist
- Decide what each folder needs. For user documents, names, contents and modification times may be enough. For
/etc, application data and anything with keys, ownership, modes, ACLs and links matter. - Read your tool's metadata documentation for both ends. Note what it carries to your object storage, where it stores it, and which tool can read it back.
- Check the 2 KB user-metadata limit against the attributes you plan to carry.
- Decide how links, hard links, empty folders and special files are handled, and write it down.
- Consider archives for system data. Formats like tar can record ownership, modes and, with the right options, extended attributes and ACLs inside the archive, independent of the object store's metadata.
- Plan for metadata drift. Use a verified refresh that actually rewrites changed metadata, or create a fresh coherent archive. Re-running an unchanged sync is not enough.
- Enable versioning deliberately, with a retention rule you have costed.
- Verify data and metadata separately. Use checksums that match how objects were uploaded, then compare owner, mode and times on a test restore.
- Test a restore to a clean server, as the account the real restore would use, and compare the result with the source.
- Record the non-ASCII and legacy-encoded names in the source, and confirm they come back unchanged.
Risks and limits
- Provider differences. This article uses the Amazon S3 user guide. S3-compatible services may differ in metadata limits, checksum support, versioning and Last-Modified behaviour.
- Tool differences. rclone is used as a documented example. Other tools store Linux metadata under different keys, or not at all; a bucket written by one tool may not restore metadata with another.
- ACLs and security labels. No source here describes carrying POSIX ACLs, NFSv4 ACLs or SELinux contexts to S3 as object metadata.
- Special files and hard links were not confirmed in the documentation.
- Not covered. Encryption, object lock, storage classes with retrieval delays, and costs of HEAD requests at scale.
Sources
-
Amazon S3, Deleting object versions: https://docs.aws.amazon.com/AmazonS3/latest/userguide/DeletingObjectVersions.html
-
Amazon S3 User Guide, Working with object metadata: https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingMetadata.html
- Amazon S3 User Guide, Naming Amazon S3 objects: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
- Amazon S3 User Guide, Checking object integrity in Amazon S3: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html
- Amazon S3 User Guide, Retaining multiple versions of objects with S3 Versioning: https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html
- rclone documentation, Usage (metadata support and flags): https://rclone.org/docs/
- rclone documentation, Amazon S3 backend: https://rclone.org/s3/
- rclone documentation, Local Filesystem backend: https://rclone.org/local/
- rclone documentation, Overview of cloud storage systems: https://rclone.org/overview/
This article was originally published on .