Skip to content

S3 compatibility

Tested, not claimed.

35 operations and features are supported, 4 partially, and 12 not yet. Last verified 2026-10-07.

SwiftFS claims compatibility only where tests prove it. Every operation marked Supported is exercised by automated tests using real clients:

  • AWS SDK for Go v2 (service/s3 v1.114) over TLS, through tests/integration (make test-integration).
  • minio-go v7.3 over plain HTTP, which uses per-chunk signed streaming, also in tests/integration.
  • aws-cli 2.37, rclone 1.75 and s3cmd against a running server, through tests/compat/run.sh (make test-compat).
  • AWS SDK for JavaScript v3 (3.1147) running a typical web-application flow (presigned browser upload with CORS, public media, private downloads, lib-storage multipart), through tests/compat/js (make test-js).

Authentication

Authentication
FeatureStatusNotes
SigV4 Authorization headerSupportedCross-checked against the AWS SDK signer; ±15 min clock skew
SigV4 presigned URLs (GET, PUT)SupportedUp to 7 days. response-* overrides honored.
UNSIGNED-PAYLOAD and signed SHA-256 payloadsSupportedSHA-256 verified before commit
STREAMING-AWS4-HMAC-SHA256-PAYLOADSupportedPer-chunk signatures (minio-go, AWS published example)
STREAMING-UNSIGNED-PAYLOAD-TRAILERSupportedAWS SDKs' default for streamed uploads; trailer checksum verified
STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILERPartialImplemented, verified by unit tests; no client in the suite sends it yet
Signature Version 2Not supportedDeprecated by AWS; clients default to V4
Anonymous accessSupportedOnly where a bucket policy allows it (Principal: "*"). response-* overrides are refused for anonymous requests, as in S3.
STS / temporary credentialsNot supported
POST Object (browser form upload)Not supportedPlanned:Use presigned PUT today

Addressing

Addressing
FeatureStatusNotes
Path-style (host/bucket/key)Supported
Virtual-hosted style (bucket.host/key)SupportedEnabled by SWIFTFS_S3_DOMAIN (needs wildcard DNS and TLS). Tested with the AWS SDK's default (UsePathStyle=false).

Buckets

Buckets
OperationStatusNotes
ListBucketsSupportedprefix filter; returns all buckets in one page
CreateBucketSupportedLocation constraint must match SWIFTFS_REGION. Names are global across accounts.
HeadBucketSupportedReturns x-amz-bucket-region
DeleteBucketSupportedMust have no objects; in-progress multipart uploads are aborted
GetBucketLocationSupported
GetBucketVersioningSupportedAlways unversioned (empty configuration)
ListObjectVersionsSupportedBuckets are unversioned, so each object is listed as its only version, null, as S3 does for a bucket that never had versioning. prefix, delimiter, max-keys, key-marker, version-id-marker, encoding-type. versionId=null is accepted wherever a version ID is.
PutBucketVersioningNot supportedPlanned:V2
Get/Put/DeleteBucketPolicySupportedIAM policy subset: Principal "*" only, Action/NotAction and Resource with wildcards, IpAddress/NotIpAddress on aws:SourceIp. Anything else is rejected (MalformedPolicy), never ignored. The owner can always manage the policy (lockout protection).
GetBucketPolicyStatusSupportedIsPublic
Get/Put/DeleteBucketCors and OPTIONS preflightSupportedS3 CORSConfiguration (≤ 100 rules, one wildcard per origin or header); CORS headers on actual requests, errors included: a request refused before its bucket is resolved (a bad or expired signature, a throttled key) still gets the bucket's CORS headers, so browsers can read the error (the lookup counts against the client IP's anonymous rate limit). Origins in SWIFTFS_CORS_ORIGINS (a management console) are allowed on every bucket after its own rules (an extension; S3 has no equivalent)
Lifecycle, tagging, encryption, website, logging, notifications, replication, object lock, ownership controls, public access blockNot supportedPlanned:Lifecycle in V2
Bucket ACLsNot supportedBuckets behave as S3's default BucketOwnerEnforced

Objects

Objects
OperationStatusNotes
PutObjectSupportedUp to SWIFTFS_MAX_OBJECT_SIZE (≤ 5 GiB). Content-MD5, x-amz-checksum-* (CRC32, CRC32C, CRC64NVME, SHA-1, SHA-256), x-amz-meta-* (2 KB), standard headers, x-amz-tagging stored
Conditional PUT (If-None-Match: *, If-Match)SupportedEvaluated atomically with the write
GetObjectSupportedSingle byte ranges, partNumber, If-Match/If-None-Match/If-(Un)Modified-Since, response-* overrides, x-amz-checksum-mode
HeadObjectSupportedSame as GetObject, without a body
DeleteObjectSupportedDeleting a missing key returns 204
DeleteObjectsSupportedUp to 1,000 keys; quiet mode; Content-MD5 or checksum verified; each key authorized separately
CopyObjectSupportedWithin and across buckets of the same account; COPY/REPLACE metadata and tagging directives; x-amz-copy-source-if-*
GetObjectAclPartialReturns owner FULL_CONTROL
PutObjectAclPartialAccepts private and bucket-owner-full-control only (AccessControlListNotSupported otherwise, as S3 with ACLs disabled)
Multiple byte ranges in one GETNot supportedIgnored (whole object returned), as in S3
Object tagging API (Get/Put/DeleteObjectTagging)Not supportedPlanned
GetObjectAttributes, RestoreObject, SelectObjectContentNot supported
Server-side encryption (SSE-S3, SSE-KMS, SSE-C)Not supportedPlanned:V2. Requests asking for SSE are rejected, never silently stored unencrypted.
Object Lock, retention, legal holdNot supportedPlanned:V2
Storage classes other than STANDARDNot supportedInvalidStorageClass

Listing

Listing
OperationStatusNotes
ListObjectsV2Supportedprefix, delimiter, max-keys (≤ 1000), continuation-token, start-after, fetch-owner, encoding-type=url
ListObjects (v1)Supportedmarker, NextMarker with a delimiter
Byte-order key listing including UnicodeSupported

Multipart uploads

Multipart uploads
OperationStatusNotes
CreateMultipartUploadSupportedMetadata, checksum algorithm and type (COMPOSITE, FULL_OBJECT)
UploadPartSupportedParts 1–10,000, ≤ 5 GiB each; re-upload replaces
CompleteMultipartUploadSupportedOrder, ETag, size and checksum validation; no data copied
AbortMultipartUploadSupported
ListPartsSupportedmax-parts, part-number-marker
ListMultipartUploadsPartialprefix, markers, max-uploads; delimiter returns NotImplemented
UploadPartCopySupportedWith x-amz-copy-source-range; copy-source conditions; whole single-part sources re-verified
Automatic cleanup of abandoned uploadsSupportedAfter SWIFTFS_MULTIPART_EXPIRY

Tools

Tools
ToolVerified operations
aws-cli 2.37s3 mb/cp/ls/sync/rm --recursive/rb/presign, 200 MiB multipart upload, parallel ranged download, s3api head-object/put-object with metadata, server-side cp, s3api put/get/delete-bucket-policy, put/get/delete-bucket-cors, upload-part-copy
rclone 1.75mkdir, copy, check (sizes and hashes), 200 MiB multipart, lsf -R, purge
s3cmdmb, put, ls, get, del, rb
AWS SDK for Go v2Everything in the integration suite, including default integrity checksums and trailers
minio-go v7MakeBucket, PutObject (signed streaming, multipart), GetObject, ListObjects, RemoveObject
AWS SDK for JavaScript v3CORS and policy configuration, browser preflight and presigned PUT from an allowed origin, anonymous public read, refused private read, presigned download with response-content-disposition, lib-storage 20 MiB multipart, ranged reads, prefix listing

Service protections

These are SwiftFS behaviors, expressed with S3 error codes so clients react correctly:

Service protections
ProtectionResponse
Rate limits per access key and per client IP (anonymous)503 SlowDown, which SDKs retry with backoff
Per-account quotas (stored bytes, objects, buckets)403 QuotaExceeded

Error behavior

Errors use S3's XML format, codes and status codes. HEAD errors carry no body. Every response has x-amz-request-id, x-amz-id-2 and X-SwiftFS-Request-ID (all the same value, also present in the server log). Requests for features SwiftFS does not implement fail with NotImplemented (501) instead of being silently accepted.

Ceph s3-tests

Ceph s3-tests is the most widely used independent S3 conformance suite. make s3-tests runs it against a fresh server in CI, and fails when a test fails without a listed reason.

Of the 886 tests in the suite's S3 files (test_s3.py and test_headers.py, commit 5522d1c), 245 pass, 478 need a feature SwiftFS doesn't implement, 49 expect Ceph-only behavior, 14 meet a deliberate difference, 5 can't fail as written and 95 are skipped by the suite. 245 of the 259 tests that only use features SwiftFS implements pass (94.6%). Every failure has a reason in s3-tests.md. Last run: 2026-10-11.

Next to verify

This page is generated from SwiftFS Core's compatibility document, which changes only when the tests do.