S3 Compatibility¶
Record Store implements a subset of the S3 API. This page is derived from the capability registry in the source, which is kept in step with the routing and protocol tests.
Supported¶
| Capability | Notes |
|---|---|
SigV4HeaderAuthentication |
The only accepted signing method |
PresignedGetObject |
Up to 7 days |
PresignedPutObject |
Up to 7 days |
BucketOperations |
Create, delete, head, list |
BucketCors |
Get, put, delete |
ObjectOperations |
Put, get, head, delete |
ListObjectsV2 |
Prefix, delimiter, pagination |
MultipartUpload |
Create, upload part, complete, abort, list |
ObjectVersioning |
Enable, suspend, list versions, delete markers |
CopyObject |
Server-side copy |
RangeAndConditionalReads |
Range, If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since |
ClientSha256Checksums |
x-amz-content-sha256 |
Unsupported¶
| Capability | Instead |
|---|---|
UploadPartCopy |
Download and re-upload the part |
ServerSideEncryptionHeaders |
Encryption is a deployment setting, not per request |
AccessControlLists |
Policies |
ObjectLock |
Versioning plus a deny policy on s3:DeleteObjectVersion |
AwsChunkedEncoding |
Configure the SDK to send unsigned or fully-signed payloads |
Requests for an unsupported operation return 501 NotImplemented.
Client requirements¶
Path-style addressing¶
Virtual-hosted style (https://bucket.storage.example.com/key) is not supported.
Every SDK has a setting for this:
| SDK | Setting |
|---|---|
| AWS CLI | --endpoint-url (path-style is used automatically) |
| boto3 | config=Config(s3={"addressing_style": "path"}) |
| Go v2 | o.UsePathStyle = true |
| JavaScript v3 | forcePathStyle: true |
| Rust | .force_path_style(true) |
Region¶
Any region works, but it must be consistent — SigV4 signs it. us-east-1 is the
conventional choice.
Checksums¶
Newer AWS SDKs default to aws-chunked trailing checksums, which Record Store does
not accept. If uploads fail with NotImplemented:
export AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
export AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
Query parameters¶
Bucket-level¶
| Parameter | Effect |
|---|---|
?cors |
CORS configuration |
?versioning |
Versioning state |
?versions |
List object versions |
?uploads |
List in-progress multipart uploads |
ListObjectsV2¶
| Parameter | Notes |
|---|---|
list-type |
2 |
prefix |
|
delimiter |
|
max-keys |
|
continuation-token |
|
start-after |
A duplicated parameter is a 400 InvalidRequest rather than a silent last-wins.
Object-level¶
| Parameter | Operation |
|---|---|
?versionId=<id> |
Read or delete a specific version |
?uploads |
Initiate a multipart upload |
?uploadId=<id>&partNumber=<n> |
Upload a part |
?uploadId=<id> |
Complete, abort, or list parts |
Bucket names¶
3–63 bytes, lowercase letters, digits, -, and .. Must begin and end with a letter
or digit. No ... Not an IPv4 address.
Reserved:
| Prefixes | xn--, sthree- |
| Suffixes | -s3alias, --ol-s3 |
| Exact names | record-store-system, record-store-internal |
Errors¶
Errors are XML in the S3 shape:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist</Message>
<Resource>/uploads/missing.txt</Resource>
<RequestId>...</RequestId>
</Error>
The request ID is also in the x-amz-request-id response header. See
Error Reference.
Verified against real SDKs¶
The repository's compatibility suite runs against a live server with these pinned versions:
| SDK | Version |
|---|---|
github.com/aws/aws-sdk-go-v2/service/s3 |
1.107.3 |
boto3 |
1.43.77 |
@aws-sdk/client-s3 |
3.1115.0 |
@aws-sdk/s3-request-presigner |
3.1115.0 |
Tools¶
| Tool | Works | Notes |
|---|---|---|
| AWS CLI | Yes | --endpoint-url |
s3cmd |
Yes | host_bucket must be path-style |
rclone |
Yes | Provider Other, force_path_style |
mc |
Yes | Standard S3 endpoint configuration |
Extensions¶
Two things Record Store adds beyond S3:
- Share links —
/s/<token>on the console, a page for a person. - Embed links —
/e/<token>on the storage endpoint, raw bytes for a website.
Neither is part of the S3 API, and neither requires a signature. Both are managed through the management API.