PutBucketLifecycle
PutBucketLifecycle is the older, deprecated way to replace a bucket's lifecycle rules - the rules
that tidy a bucket up by expiring old versions and abandoned uploads
(Lifecycle policies explains them). STRG answers a request in its
format with 501 NotImplemented, so a client knows straight away, and the bucket's existing rules
stay exactly as they were. PutBucketLifecycleConfiguration
is the way to set lifecycle rules: it sends the same request, with each rule's prefix inside
Filter.
Amazon S3 deprecated PutBucketLifecycle in favour of
PutBucketLifecycleConfiguration. The AWS SDK for
JavaScript v3 does not offer this operation at all; the AWS CLI (put-bucket-lifecycle) and
boto3 (put_bucket_lifecycle) still do.
- This operation's format puts a top-level
Prefixon every rule, and STRG answers such a rule with501 NotImplemented. Nothing about the bucket changes. - A document whose rules carry
Filterrather thanPrefixis the PutBucketLifecycleConfiguration format, and STRG handles it exactly as that operation does. x-amz-expected-bucket-owneris welcome and has nothing to check: a key only ever reaches buckets of its own account.
When you'd use it
- An older script or backup tool that still calls
put-bucket-lifecyclegets a clear501 NotImplementedand leaves the bucket's rules untouched, so nothing changes without anyone noticing. - Moving such a script over takes two small changes - the command, and the prefix moving into
Filter- and the examples below show both side by side. - A tool that sends the newer
Filterformat under this name keeps working: STRG reads the document as PutBucketLifecycleConfiguration and stores the rules.
Request
PUT /?lifecycle HTTP/1.1
Host: my-bucket.s3.eu-central-1.strg.com
Authorization: AWS4-HMAC-SHA256 Credential=...
x-amz-date: 20260926T120000Z
x-amz-content-sha256: <SHA-256 of the body>
Content-MD5: <base64 MD5 of the body>
Content-Type: application/xml
<LifecycleConfiguration>...</LifecycleConfiguration>
Path-style, the same request is PUT /my-bucket?lifecycle on s3.eu-central-1.strg.com;
Addressing has the details.
Permissions
The access key needs Manage lifecycle rules (bucket-lifecycle:write). A key limited to
certain buckets reaches only those. A key prefix does not narrow this operation, since the
configuration belongs to the whole bucket. A key without the permission gets 403 AccessDenied
before the body is read. Access keys has the full picture.
URI parameters
| Name | Type | Required | Description |
|---|---|---|---|
Bucket | String | Yes | The bucket whose lifecycle rules would be replaced. |
lifecycle | Flag | Yes | Selects the lifecycle subresource. Takes no value. |
Any other query parameter gets 501 NotImplemented, so a client knows straight away, except the
X-Amz-* parameters of a presigned URL and the x-id parameter the JavaScript SDK adds.
Request headers
| Name | Type | Required | Description |
|---|---|---|---|
Content-MD5 | String | Conditional | Base64 MD5 of the body. One integrity header is required: this or an x-amz-checksum-* header, and a request with neither gets 400 InvalidRequest. A value that does not match the body is 400 BadDigest. The AWS CLI and SDKs send a checksum automatically. |
x-amz-sdk-checksum-algorithm | String | No | The algorithm of the x-amz-checksum-* header the SDK sends. Accepted. |
x-amz-expected-bucket-owner | String | No | Welcome, with nothing to check: an access key only ever reaches its own account's buckets. |
Request body
A LifecycleConfiguration document of at most 2 MiB. This operation's rule format always
carries a top-level Prefix, which STRG answers first, so the rest of the rule is never read:
| Element | Type | Required | Description |
|---|---|---|---|
Rule | Container | Yes | One lifecycle rule. Repeated. |
Rule/Prefix | String | Yes | Answered with 501 NotImplemented on any rule that carries it. The same prefix in Filter/Prefix, sent as PutBucketLifecycleConfiguration, sets the rule. |
Rule/ID | String | No | Never read: the rule's Prefix has already been answered. |
Rule/Status | String | Yes | Never read: the rule's Prefix has already been answered. |
Rule/Expiration | Container | No | Never read: the rule's Prefix has already been answered. |
Rule/NoncurrentVersionExpiration | Container | No | Never read: the rule's Prefix has already been answered. |
Rule/AbortIncompleteMultipartUpload | Container | No | Never read: the rule's Prefix has already been answered. |
Rule/Transition | Container | No | Never read: the rule's Prefix has already been answered. Every object stays in one storage class, so neither operation has transitions. |
Rule/NoncurrentVersionTransition | Container | No | Never read: the rule's Prefix has already been answered. Neither operation has transitions, for the same reason. |
The actions STRG stores and their limits are on PutBucketLifecycleConfiguration and Lifecycle policies.
Response
A request in this operation's format always gets an error document, so there is no success
response to describe. The x-amz-request-id header carries the request ID, handy for a support
request.
Errors
The answers this operation can give, and the situation behind each. Once the key is accepted in this endpoint's region, the request is answered before the bucket is looked up, so a bucket that does not exist gets the same answer as one that does.
| Code | HTTP status | When |
|---|---|---|
NotImplemented | 501 | A rule carries a top-level Prefix - every request in this operation's format - or the request carries a query parameter this operation does not take. |
MalformedXML | 400 | The body is not well-formed XML, not UTF-8, its root element is not LifecycleConfiguration, or it uses a comment, CDATA section, DOCTYPE, processing instruction or namespace prefix. |
InvalidRequest | 400 | The request carries neither Content-MD5 nor an x-amz-checksum-* header. |
BadDigest | 400 | Content-MD5 does not match the body. |
XAmzContentSHA256Mismatch | 400 | x-amz-content-sha256 does not match the body. |
MaxMessageLengthExceeded | 400 | The body is larger than 2 MiB. |
AccessDenied | 403 | The access key does not hold Manage lifecycle rules, or the bucket is outside its scope. |
InvalidAccessKeyId | 403 | The access key does not exist, has expired or been revoked - or it was created moments ago and is not yet usable in this endpoint's region, where the account already stores data, in which case the same request works shortly after. |
NoSuchBucket | 404 | The account has no storage in this endpoint's region yet. The bucket is not looked for, whatever the body holds. |
SignatureDoesNotMatch | 403 | The request signature does not match. |
RequestTimeTooSkewed | 403 | The request time is more than 15 minutes from the server's. |
AuthorizationHeaderMalformed | 400 | The signature's credential scope names a region other than the endpoint's. |
ServiceUnavailable | 503 | A temporary failure. The AWS SDKs retry it on their own. |
Differences from Amazon S3
| Aspect | Amazon S3 | STRG |
|---|---|---|
| The operation | Deprecated, still accepted | 501 NotImplemented, with the bucket's rules unchanged. PutBucketLifecycleConfiguration sets the same rules. |
x-amz-expected-bucket-owner | Checked against the bucket owner | Welcome, with nothing to check: a key only reaches its own account's buckets |
Differences from Amazon S3 covers the ones that apply to every operation.
Examples
Moving from this operation to PutBucketLifecycleConfiguration takes two changes: the command,
and the prefix moving into Filter. Here is a rule that removes objects under logs/ 30 days
after upload, previous versions 7 days after they are replaced, and incomplete multipart uploads
after 2 days:
- AWS CLI
- Python (boto3)
- JavaScript (AWS SDK v3)
Instead of put-bucket-lifecycle with "Prefix": "logs/" on the rule:
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--endpoint-url https://s3.eu-central-1.strg.com \
--region eu-central-1 \
--lifecycle-configuration '{
"Rules": [
{
"ID": "expire-logs",
"Filter": { "Prefix": "logs/" },
"Status": "Enabled",
"Expiration": { "Days": 30 },
"NoncurrentVersionExpiration": { "NoncurrentDays": 7 },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 2 }
}
]
}'
Instead of put_bucket_lifecycle with "Prefix": "logs/" on the rule:
import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://s3.eu-central-1.strg.com",
region_name="eu-central-1",
)
s3.put_bucket_lifecycle_configuration(
Bucket="my-bucket",
LifecycleConfiguration={
"Rules": [
{
"ID": "expire-logs",
"Filter": {"Prefix": "logs/"},
"Status": "Enabled",
"Expiration": {"Days": 30},
"NoncurrentVersionExpiration": {"NoncurrentDays": 7},
"AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 2},
}
]
},
)
The AWS SDK for JavaScript v3 has no command for this deprecated operation.
PutBucketLifecycleConfigurationCommand sends the same request and sets the rule:
import { PutBucketLifecycleConfigurationCommand, S3Client } from "@aws-sdk/client-s3";
const client = new S3Client({
endpoint: "https://s3.eu-central-1.strg.com",
region: "eu-central-1",
});
await client.send(
new PutBucketLifecycleConfigurationCommand({
Bucket: "my-bucket",
LifecycleConfiguration: {
Rules: [
{
ID: "expire-logs",
Filter: { Prefix: "logs/" },
Status: "Enabled",
Expiration: { Days: 30 },
NoncurrentVersionExpiration: { NoncurrentDays: 7 },
AbortIncompleteMultipartUpload: { DaysAfterInitiation: 2 },
},
],
},
}),
);