Skip to content

Compatibility

Which S3 features Shelby supports, which work differently, and which are not available.

Shelby implements the S3 calls that object storage workloads use: put, get, head, range reads, multipart uploads, listing and delete. This page lists how Shelby handles every part of the S3 API, so you can check your workload before you move it.

Each row is marked:

  • Supported: works as it does on Amazon S3.
  • Supported with differences: works, with a difference noted alongside it.
  • Not supported: not available. The notes give the alternative.

S3 features

Objects

CapabilityStatusNotes
PutObject, GetObject, HeadObject SupportedSingle PUTs up to 5 GiB. Range reads are supported.
Read-after-write consistency Supported with differencesGET and HEAD see a new or overwritten object as soon as the write returns. A new object can take a few seconds to appear in listings. See Known compatibility issues.
Overwrite an existing key SupportedA plain PUT replaces the object, as a full new write. Reads see the new version as soon as the PUT returns.
Create-only writes (If-None-Match: *) SupportedReturns 412 PreconditionFailed if the key already exists.
Conditional overwrite (If-Match on PUT) Not supportedNot enforced on the hosted endpoint yet: the write succeeds whether or not the ETag matches. Do not rely on it for concurrency control. See Known compatibility issues.
Conditional reads (If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since) Not supportedAccepted and ignored. GET always returns the full object.
DeleteObject SupportedReturns 204, including for a key that does not exist. If-Match supports exact ETags and * for an existence check.
DeleteObjects (batch, up to 1,000 keys) Supported with differencesUp to 1,000 keys. Keys that do not exist are reported as deleted, as on S3. Per-key ETags are supported and failed conditions return per-key errors. The AWS SDK for JavaScript sends this request in a form Shelby does not recognise yet. See Known compatibility issues.
CopyObject, UploadPartCopy, aws s3 mv Not supportedReturns 501 NotImplemented. Download and re-upload instead.

Multipart uploads

CapabilityStatusNotes
Create, UploadPart, Complete, Abort, ListParts, ListMultipartUploads Supported with differencesParts are 5 MiB to 5 GiB. ListMultipartUploads from the AWS SDK for JavaScript gets the wrong answer. See Known compatibility issues.
Parts per upload Supported with differencesUp to 3,000 parts (S3 allows 10,000). Use parts of at least 10 MiB, which fit files up to about 29 GiB.

Listing

CapabilityStatusNotes
ListObjects, ListObjectsV2 Supported with differencesPrefix, delimiter and pagination work. max-keys above 1,000 is rejected rather than clamped. fetch-owner is ignored. New objects can take a few seconds to appear.

Integrity

CapabilityStatusNotes
ETags SupportedMD5 of the content for single-part objects, S3's <md5>-<parts> form for multipart objects. Objects written before mid-October 2026 have older ETags that are not MD5s.
Content-MD5 upload check SupportedA mismatch is rejected with 400 BadDigest.
Flexible checksums (x-amz-checksum-*, aws-chunked uploads) Not supportedChecksum headers are accepted but not verified. aws-chunked uploads, which the AWS CLI and boto3 send by default, are refused with 501: each quickstart shows the one setting that turns them off.

Object metadata

CapabilityStatusNotes
Content-Type, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Expires SupportedStored and returned. Objects stored before Shelby kept metadata come back as binary/octet-stream.
User metadata (x-amz-meta-*) SupportedStored and returned, up to 2 KB per object as on S3. This includes the modification time rclone writes.
Object tagging, storage classes, object lock Not supportedHeaders are accepted and ignored. Every object is STANDARD. The tagging, retention and legal-hold APIs are refused.

Security and access

CapabilityStatusNotes
AWS Signature Version 4 SupportedHeader-signed requests from any S3 client, with any signing region. Presigned URLs must be signed with default. Use default everywhere: it's the region Shelby reports.
Server-side encryption Supported with differencesAlways on: every object is encrypted at rest with keys Shelby manages (SSE-S3). SSE-C and SSE-KMS are refused with 501.
Presigned URLs for downloads (GET, HEAD) SupportedOne object per URL, for up to 7 days. Sign with region default. See Presigned URLs.
Presigned uploads, deletes and listings Not supportedRefused with 405 or 400. Upload, delete and list from a server with your credentials. To share a prefix, use a folder share.
CORS and browser uploads Not supportedYou can't configure CORS. Browsers can open presigned links and load them in <img> and <video>, but don't build on cross-origin fetch. Upload from a server.
Authentication error format Supported with differencesBad or missing credentials return 401 with a plain-text body instead of an S3 XML error. See Troubleshooting.

Buckets

CapabilityStatusNotes
Bucket name Supported with differencesCreate buckets in the console. Each access key reaches only its own bucket, and ListBuckets returns only that bucket. You can't create, delete or rename buckets over the S3 API. Use path-style addressing.
GetBucketLocation, GetBucketVersioning, GetBucketAcl Supported with differencesAnswered with fixed values: versioning off, owner-only ACL. GetBucketLocation reports default. The AWS SDK for JavaScript gets the wrong answer to these. See Known compatibility issues.
Bucket configuration: lifecycle, versioning, policy, CORS, website, replication, logging, notifications, tagging Not supportedObjects do not expire and are not versioned. Some of these calls are answered with 404 or a plain object listing instead of 501. See Known compatibility issues.
DeleteBucket Not supportedBuckets are managed in the console, not over the S3 API.

Clients

These clients are tested against the hosted endpoint. Each quickstart shows the full configuration.

ClientStatusWhat to setNotes
AWS CLI v2Works with settingsrequest_checksum_calculation = when_requiredaws s3 mv and Shelby-to-Shelby aws s3 cp need server-side copy, which isn't supported.
Python (boto3)Works with settingsrequest_checksum_calculation="when_required"
JavaScript (AWS SDK v3)Works with settingsresponseChecksumValidation: "WHEN_REQUIRED", for presigned URLs. requestChecksumCalculation: "WHEN_REQUIRED" is optionalDeleteObjectsCommand doesn't work yet. Delete keys one at a time.
rcloneWorks as-isNone required. --checksum is recommended on copy and sync
DuckDB (httpfs)Works with settingsURL_STYLE 'path', and s3_uploader_max_parts_per_file = 3000 for large writesTested writing and reading Parquet and CSV, including multipart writes. DuckDB can't delete objects.
MinIO Client (mc)Works with settingsMC_REGION=default, and --path on in mc alias setTested listing, uploading and downloading objects.

Other S3 clients usually work too, as long as they can use path-style addressing and send requests without aws-chunked checksums.

Why some things work differently

You manage buckets in the console

On Shelby, you create buckets in the console, not with S3 calls. A project can have many buckets, and each access key belongs to one of them (see Projects, buckets and access keys). So, over the S3 API:

  • You can't create, delete or rename buckets. CreateBucket on the access key's own bucket succeeds without doing anything, so clients that create the bucket before writing keep working. DeleteBucket is not available.
  • ListBuckets returns only the access key's bucket. To work with several buckets, use each bucket's own access key.
  • Clients must use path-style addressing. The endpoint doesn't serve bucket names as hostnames (<bucket>.<endpoint>).
  • Bucket-level configuration such as lifecycle rules, policies and CORS doesn't exist.

Every write is a durable commit

A PUT returns once the object is erasure-coded across many storage nodes and the write is committed. That's why:

  • Writes take longer than on S3.
  • An overwrite stores a complete new object. Shelby has no metadata-only update.
  • Re-uploading an unchanged file repeats the whole write, so sync tools should skip unchanged files to save time. This is why the rclone quickstart uses --checksum.
  • Reads see a new or overwritten object as soon as the PUT returns, but it can take a few seconds to show up in listings.

Encryption is always on

Every object is encrypted at rest with keys Shelby manages. You don't need to send any encryption headers. Shelby doesn't accept customer-provided keys (SSE-C) or AWS KMS keys (SSE-KMS), and refuses requests that ask for them rather than storing the data unencrypted.

ETags

Single-part objects have the MD5 of their content as their ETag, as on S3, so identical content has identical ETags. Multipart objects use S3's <md5-of-part-md5s>-<part-count> form, which isn't the MD5 of the whole object (as on S3).

Objects written before mid-October 2026 have older ETags that aren't MD5s. Single-part ones end in -s, which tells clients such as rclone not to treat them as MD5s, so those clients compare older objects by size only.

Known compatibility issues

A few responses differ from S3 for now, each with a workaround. None of them affect the durability of stored data. See Known compatibility issues.

Last verified against the hosted endpoint on 2026-11-06.