S3 Compatibility
Fil One provides an S3-compatible API. If your application works with AWS S3, it works with Fil One — point your SDK or CLI at our endpoint and authenticate with your API keys.
Endpoint
Endpoints are region-specific. Use the endpoint for the region your bucket lives in:
| Region | Endpoint |
|---|---|
Europe (France) eu-west-1 (default) | https://eu-west-1.s3.filonecontent.com |
US East (Michigan) us-east-1 | https://us-east-1.s3.filonecontent.com |
All requests use HTTPS. HTTP connections are rejected.
Authentication
Fil One supports AWS Signature Version 4 (SigV4) authentication. Any S3 client or SDK that supports SigV4 will work without modification.
| Parameter | Value |
|---|---|
| Endpoint | https://<region>.s3.filonecontent.com |
| Region | eu-west-1 or us-east-1 |
| Signature version | SigV4 |
| Path style | Required |
| Virtual-hosted style | Not supported |
Supported operations
Specific size and count limits quoted in this table (5 TB max object, 5 GB single-PUT, 5 MB / 5 GB part sizes, 10,000 parts, 1,000-object bulk delete) are the standard AWS S3 values. Fil One's storage gateway is expected to follow them, but they have not been independently confirmed — see Limits.
eu-west-1In eu-west-1, operations that Fil One does not implement return AccessDenied (HTTP 403), not NotImplemented (501). This is confirmed by a compatibility test run against the region.
A 403 from PutBucketVersioning, PutBucketPolicy, PutBucketAcl, PutBucketEncryption, PutBucketLifecycleConfiguration, or the tagging operations means the feature is absent, not that your key lacks a permission. Don't spend time auditing your access-key scopes for these. Code that branches on NotImplemented to degrade gracefully needs to treat 403 on these operations the same way.
Bucket operations
| Operation | Status | Notes |
|---|---|---|
CreateBucket | ⚠️ Region-dependent | Supported in us-east-1. Not available in eu-west-1 — create buckets there via the dashboard. |
DeleteBucket | ⚠️ Region-dependent | Supported in us-east-1 (the bucket must be empty). Not available in eu-west-1. |
ListBuckets | ✅ Supported | |
HeadBucket | ✅ Supported | |
GetBucketVersioning | ✅ Supported | Returns Enabled for versioned buckets, Suspended is never returned. |
PutBucketVersioning | ⚠️ Region-dependent | Rejected with AccessDenied in eu-west-1, for enable as well as suspend requests: versioning there is set at bucket creation and cannot be changed over the API at all. In us-east-1, accepted for SDK compatibility, but versioning still cannot be suspended once enabled. |
GetBucketObjectLockConfiguration | ✅ Supported | Returns the bucket-level default retention policy, if set. |
PutBucketObjectLockConfiguration | ✅ Supported | Sets the default retention policy in Governance or Compliance mode. |
GetBucketEncryption | ⚠️ Region-dependent | Returns AccessDenied in eu-west-1 rather than an encryption configuration. Supported in us-east-1. Encryption is always on regardless of what this call returns. |
PutBucketEncryption | ⚠️ Region-dependent | Rejected with AccessDenied in eu-west-1, including a valid SSE-S3 default rule. In us-east-1, accepted for SDK compatibility but has no effect. Encryption cannot be modified or disabled in either region. |
DeleteBucketEncryption | ❌ Not supported | Rejected with AccessDenied in eu-west-1. Encryption cannot be disabled. |
GetBucketAcl | ❌ Not supported | ACL model is not implemented. Returns AccessDenied in eu-west-1. See ACLs. |
PutBucketAcl | ❌ Not supported | ACL model is not implemented. Rejected with AccessDenied in eu-west-1. |
GetBucketPolicy | ❌ Not supported | Bucket policies are not implemented. |
PutBucketPolicy | ❌ Not supported | Bucket policies are not implemented. Rejected with AccessDenied in eu-west-1. |
GetBucketLifecycleConfiguration | ❌ Not supported | Planned for a future release. |
PutBucketLifecycleConfiguration | ❌ Not supported | Planned for a future release. Rejected with AccessDenied in eu-west-1. |
GetBucketNotificationConfiguration | ❌ Not supported | Event notifications are not supported. |
PutBucketNotificationConfiguration | ❌ Not supported | Event notifications are not supported. |
GetBucketTagging | ❌ Not supported | Bucket and object tagging are not implemented. |
PutBucketTagging | ❌ Not supported | Bucket and object tagging are not implemented. |
GetBucketLogging | ❌ Not supported | Server access logging is not implemented. |
PutBucketLogging | ❌ Not supported | Rejected in eu-west-1 (MalformedXML, even for a well-formed configuration). |
GetPublicAccessBlock | ❌ Not supported | Public access is never permitted, so there is no block configuration to read. |
PutPublicAccessBlock | ❌ Not supported | Rejected in eu-west-1 (MalformedXML, even for a well-formed configuration). All buckets are private unconditionally. |
Object operations
| Operation | Status | Notes |
|---|---|---|
PutObject | ✅ Supported | Max object size: 5 TB (use multipart for objects > 5 GB). |
GetObject | ✅ Supported | Supports range requests (Range header). Supports VersionId to retrieve a specific version. |
DeleteObject | ✅ Supported | Creates a delete marker on versioned buckets. Pass VersionId to permanently delete a specific version. |
DeleteObjects | ✅ Supported | Bulk delete up to 1,000 objects per request. |
HeadObject | ✅ Supported | |
ListObjectsV2 | ✅ Supported | |
ListObjectVersions | ✅ Supported | Returns all versions and delete markers. Supports Prefix and KeyMarker filters. |
CopyObject | ⚠️ Region-dependent | Confirmed working in us-east-1, including copying a specific VersionId onto the current key. In eu-west-1, most copy operations pass a compatibility run, so plain server-side copy works there, but copying a specific VersionId is still unverified in that region because the test harness cannot configure versioning over the API. Verify a version-promote copy against your own bucket before relying on it. |
GetObjectRetention | ✅ Supported | Returns the Object Lock retention for a specific version. |
PutObjectRetention | ✅ Supported | Set, extend, or (via S3's bypass-governance-retention mechanism) shorten a version's retention. Requires the matching access-key permission. |
GetObjectLegalHold | ✅ Supported | Requires the matching access-key permission. |
PutObjectLegalHold | ✅ Supported | Blocks delete while a hold is active. Requires the matching access-key permission. |
GetObjectAttributes | ❌ Not supported | Returns AccessDenied in eu-west-1. Use HeadObject for size, ETag, and metadata instead. |
GetObjectAcl | ❌ Not supported | ACL model is not implemented. Returns AccessDenied in eu-west-1, including on objects uploaded with a canned-ACL header. |
PutObjectAcl | ❌ Not supported | ACL model is not implemented. Rejected with AccessDenied in eu-west-1. |
GetObjectTagging | ❌ Not supported | Object tagging is not implemented. Returns AccessDenied in eu-west-1. |
PutObjectTagging | ❌ Not supported | Object tagging is not implemented. Rejected with AccessDenied in eu-west-1. |
RestoreObject | ❌ Not applicable | Fil One has a single storage class. There are no archival tiers to restore from. |
SelectObjectContent | ❌ Not planned | S3 Select is not planned. |
Multipart upload
Multipart upload is supported through the S3 API in all regions. Note that uploads from the Fil One dashboard always use a single PutObject request, so browser uploads are bounded by the single-PUT ceiling — use the S3 API or CLI for larger objects.
| Operation | Status | Notes |
|---|---|---|
CreateMultipartUpload | ✅ Supported | |
UploadPart | ✅ Supported | Minimum part size: 5 MB (except last part). Maximum: 5 GB. |
CompleteMultipartUpload | ✅ Supported | Maximum 10,000 parts per upload. |
AbortMultipartUpload | ✅ Supported | |
ListParts | ✅ Supported | |
ListMultipartUploads | ✅ Supported |
Versioning
Versioning is opt-in and configured at bucket creation time. Once enabled on a bucket, it cannot be suspended or disabled. Every upload to an existing key on a versioned bucket creates a new version rather than overwriting.
| Operation | Status | Notes |
|---|---|---|
GetBucketVersioning | ✅ Supported | Returns Enabled for versioned buckets. |
ListObjectVersions | ✅ Supported | Lists all versions and delete markers in a bucket. |
GetObject with VersionId | ✅ Supported | Retrieves a specific historical version by ID. |
DeleteObject with VersionId | ✅ Supported | Permanently deletes a specific version, bypassing delete markers. |
PutBucketVersioning (suspend) | ❌ Rejected | Versioning cannot be suspended once enabled. Suspend requests return an error. In eu-west-1 that error is AccessDenied, and enable requests are rejected the same way. |
CopyObject with x-amz-copy-source-version-id | ⚠️ Region-dependent | Confirmed working in us-east-1 — copy a specific version onto the current key to promote it. Still unverified in eu-west-1: plain copy works there, but the version-id form could not be tested because versioning cannot be configured over the API in that region. |
The Fil One dashboard has no restore, roll-back, or "make current" action — you can list, download, and delete any prior version there, but not promote one to current. In us-east-1, you can promote an older version via the API with CopyObject (see above). In eu-west-1, plain server-side copy works but the version-id form is unverified, so test it against your own bucket first and fall back to downloading the version and uploading it again if it fails.
See Versioning for detailed usage and examples.
Object Lock
Object Lock enforces WORM (Write-Once-Read-Many) protection. Both Governance and Compliance mode are supported. Object Lock requires versioning, and both are set at bucket creation time.
Object Lock, retention, and Legal Hold work in both regions. us-east-1 is covered by an automated compatibility suite (39/39 object-lock tests passing). eu-west-1 was verified by engineering testing rather than by that suite: a compatibility run against the region could not exercise these operations, because the harness was unable to create an Object-Lock-enabled bucket to test against, which was a limitation of the test setup and not a product gap.
| Operation | Status | Notes |
|---|---|---|
GetBucketObjectLockConfiguration | ✅ Supported | Returns the bucket-level default retention policy. |
PutBucketObjectLockConfiguration | ✅ Supported | Sets the default retention (Governance or Compliance mode, 1 day – 100 years). |
GetObjectRetention | ✅ Supported | Returns the retention setting for a specific object version. |
PutObjectRetention | ✅ Supported | Extend a retention period, or shorten one via S3's bypass-governance-retention mechanism (correctly rejected without it). Requires the matching access-key permission. |
GetObjectLegalHold | ✅ Supported | Requires the matching access-key permission. |
PutObjectLegalHold | ✅ Supported | Blocks delete while a hold is active. Requires the matching access-key permission. |
Object Lock modes:
| Mode | Status |
|---|---|
| Governance | ✅ Supported — the default when you enable Object Lock. In standard S3, Governance retention can be overridden by a caller with the bypass permission, but Fil One does not currently expose a grantable bypass permission, so treat Governance objects as protected for their retention period in practice. |
| Compliance | ✅ Supported — no user, including the account owner, can delete a locked object or shorten its retention. |
See Object Lock for compliance use cases, retention configuration, and examples.
Presigned URLs
| Operation | Status | Notes |
|---|---|---|
Presigned GetObject | ✅ Supported | Generate time-limited download URLs without requiring API credentials. |
Presigned PutObject | ✅ Supported | Generate time-limited upload URLs for direct client or browser uploads. |
Server-side encryption
Encryption is always enabled on every Fil One bucket. There is nothing to configure.
| Feature | Status | Notes |
|---|---|---|
| Server-side encryption at rest | ✅ Always on | Applied automatically by the regional storage gateway — no headers required, and it cannot be disabled. |
| Encryption in transit (TLS) | ✅ Always on | All API connections use HTTPS. HTTP is rejected. |
GetBucketEncryption | ⚠️ Region-dependent | Supported in us-east-1. Returns AccessDenied in eu-west-1, so you cannot read back a configuration there. Encryption is on either way. |
PutBucketEncryption | ⚠️ Region-dependent | Rejected with AccessDenied in eu-west-1, even for a valid SSE-S3 rule. Accepted but ineffective in us-east-1. Encryption cannot be modified or disabled. |
SSE-S3 (AES256) | ⚠️ Region-dependent | Accepted in us-east-1. In eu-west-1 the bucket-level SSE-S3 configuration operations are rejected with AccessDenied. Encryption is applied automatically in both regions, so no header is needed. |
SSE-KMS (aws:kms) | ❌ Not supported | Rejected in both regions: InvalidRequest in us-east-1, and AccessDenied or InvalidRequest in eu-west-1 depending on the operation. Affects PutObject, CopyObject, and CreateMultipartUpload. Omit encryption headers, server-side encryption is applied automatically. |
| SSE-C (customer-provided keys) | ❌ Not supported | Keys are held by the regional storage operator. There is no customer-managed-key option. Requests carrying SSE-C headers are rejected in eu-west-1. |
| Client-side encryption | ✅ Optional | Encrypt data in your own application before upload. AWS's S3 Encryption Client exists only for some SDKs (Java, .NET, Go, Ruby) — not boto3, the CLI, or JS v3 — so with those you supply your own crypto. Server-side encryption is still applied on top. |
See Encryption for details.
ACLs
The S3 ACL model is not supported. Fil One does not implement bucket or object ACLs, bucket policies, or public access controls. All access requires SigV4 authentication.
How an ACL request fails depends on how you send it. Confirmed in eu-west-1:
| What you send | Behavior |
|---|---|
A canned-ACL header on an upload (--acl public-read in the AWS CLI, ACL: 'public-read' on a PutObject SDK call) | The flag is silently ignored. The upload succeeds and the object is stored, but no ACL is applied and the object does not become public. |
A dedicated ACL call (PutBucketAcl, PutObjectAcl, GetBucketAcl, GetObjectAcl) | Rejected with AccessDenied (403). |
So a tool that uploads with --acl public-read will appear to work, while a tool that sets ACLs as a separate step will fail outright. In neither case does the object become publicly readable. If you need unauthenticated access to an object, use a presigned URL.
Per-bucket access control via API key scoping is planned for a future release.
Not yet supported
| Feature | Timeline | Notes |
|---|---|---|
| Lifecycle rules (expiration, transitions) | Phase 2 | Planned. Affects archival and cleanup workflows. |
| Event notifications (SNS/SQS/Lambda triggers) | Phase 2 | Planned. |
| Object and bucket tagging | Phase 2 | Planned. |
| Additional regions | Phase 2 | eu-west-1 and us-east-1 are available today. |
| IAM / multi-user accounts / RBAC | Phase 2 | Single-user accounts only. |
| S3 Select | Not planned | |
| S3 Inventory | Not planned | |
| S3 Batch Operations | Not planned | |
| Multiple storage classes | Not planned | Single storage class. |
Error responses
Fil One returns standard S3 error XML, in the shape below, for all error conditions.
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>NoSuchBucket</Code>
<Message>The specified bucket does not exist.</Message>
<BucketName>my-bucket</BucketName>
<RequestId>abc123</RequestId>
</Error>
The format is standard, but the specific code returned for a given condition does not always match AWS. If your application only surfaces error messages, no changes are needed. If it branches on error codes or HTTP statuses, review the deviations below.
See the Error Reference for a full list of error codes.
Known error-code deviations in eu-west-1
Confirmed by a compatibility test run against the region.
| Condition | AWS S3 returns | Fil One eu-west-1 returns |
|---|---|---|
| Any unimplemented operation | NotImplemented (501) | AccessDenied (403) |
| Reading a bucket or key you cannot see | NoSuchBucket / NoSuchKey (404) | AccessDenied (403) |
| A checksum that does not match the body | BadDigest | InvalidArgument |
An unsatisfiable Range header | InvalidRange | InvalidArgument |
| An invalid object tag | InvalidTag | BadRequest |
CreateBucket on a bucket you already own | BucketAlreadyExists in most regions | BucketAlreadyOwnedByYou |
A malformed PutPublicAccessBlock or PutBucketLogging body | MalformedXML for genuinely bad XML only | MalformedXML even for a well-formed body, since neither operation is implemented |
Some invalid requests are also accepted where AWS rejects them (HTTP 200 or 204 instead of 400). Do not rely on the gateway to validate request parameters for you: validate on the client side where correctness matters.
Known behavioral issues in eu-west-1
These are confirmed deviations that can affect a correctly written S3 client. They are open engineering issues, not intended behavior.
| Area | Issue | Workaround |
|---|---|---|
| Pagination | ListObjects may return a NextMarker with an internal suffix appended to the key (for example asdf[...] instead of asdf). Feeding that value back as the next Marker will not resume where you left off. | Prefer ListObjectsV2 with ContinuationToken, which is unaffected. If you must use ListObjects, do not trust NextMarker; page using the last returned key instead. |
| URL encoding | With EncodingType=url, a space in a key or prefix is encoded as + rather than %20. Most SDKs decode %20 only, so keys with spaces can come back wrong. | Avoid spaces in key names, or decode + as a space yourself when you request URL encoding. |
| Checksums | Additional-checksum operations are unreliable. CompleteMultipartUpload may omit ChecksumType from its response, and checksum mismatches surface as InvalidArgument rather than BadDigest. | Verify integrity with ETags, or compare a hash you compute yourself after download. |
Differences from AWS S3
Fil One is S3-compatible, not an S3 clone. A few behaviors differ:
| Behavior | AWS S3 | Fil One |
|---|---|---|
| Versioning | Configurable — can be enabled, suspended, or left off per bucket. | Opt-in at bucket creation. Once enabled, cannot be suspended or disabled. No restore/roll-back from the dashboard; achievable via the API in us-east-1 using CopyObject. |
| Server-side copy | CopyObject supported. | Confirmed working in us-east-1. In eu-west-1 plain copy works, but the version-id form (promoting an old version) is unverified. |
| Encryption | Optional and configurable. Off by default for older buckets. | Always on. Cannot be disabled. Keys are held by the regional storage operator; no customer-managed keys. |
| Bucket management | CreateBucket and DeleteBucket supported via API. Requires an empty bucket to delete. | Region-dependent. Supported via API in us-east-1; in eu-west-1 buckets are managed through the dashboard only. |
| IAM and policies | Full IAM with users, roles, and bucket policies. | Single-user accounts. No IAM or bucket policies. Key-based auth only. |
| Public access | Configurable via ACLs and bucket policies. | No public access. All requests require authentication. Canned-ACL headers on uploads are ignored rather than rejected, and never make an object public. |
| Error codes for missing features | NotImplemented (501). | AccessDenied (403) in eu-west-1. A 403 on a bucket-configuration call means the feature is absent, not that your key lacks permission. |
| Lifecycle rules | Supported (expiration, storage class transitions). | Not supported. Planned for a future release. |
| Object Lock modes | Compliance and Governance. | Compliance and Governance, in both regions, with Legal Hold. |
| Storage classes | Multiple (Standard, IA, Glacier, etc.). | Single storage class. |
| Regions | 30+ globally. | Two: eu-west-1 and us-east-1. Additional regions planned. |
| Data retention after deletion | Object is immediately and permanently deleted. | Object is immediately inaccessible in Fil One, but the underlying Filecoin storage may persist for a bounded period until the sealed sector naturally expires. That residual data stays encrypted. |