By misbah
When I try setting expiration via nodejs (code below)
import "dotenv-defaults/config";
import { PutBucketLifecycleConfigurationCommandInput } from "@aws-sdk/client-s3";
const s3Client = new S3({
endpoint: "https://sgp1.digitaloceanspaces.com",
region: "sgp1",
credentials: {
accessKeyId: process.env.ACCESS_KEY,
secretAccessKey: process.env.SPACES_SECRET
}
});
const params: PutBucketLifecycleConfigurationCommandInput = {
Bucket: "maxchat",
LifecycleConfiguration: {
Rules: [
{
Expiration: {
Days: 1,
},
Filter: {
Prefix: "oneday/",
},
Status: "Enabled",
ID: "Expiration1Days",
},
],
},
};
const run = async () => {
try {
const data = await s3Client.putBucketLifecycleConfiguration(params);
console.log("data", data);
} catch (err) {
console.log("Error", err);
}
};
run();
and I try to get my object (file) in other prefix (folder) using nodejs (code below)
// some import ...
export const params: GetObjectCommandInput = {
Bucket: "<my-space-name>",
Key: "other-perfix/<my-file>.txt",
};
// Generates the URL.
export const run = async () => {
try {
const data = await s3Client.getObject(params); // Adjustable expiration.
console.log("Contents:", data.Expiration);
return data;
} catch (err) {
console.log("Error", err);
}
};
run();
and the result (concole.log) is
Contents: {
'$metadata': {
httpStatusCode: 200,
requestId: undefined,
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
AcceptRanges: 'bytes',
Expiration: 'expiry-date="Tue, 06 Sep 2022 15:03:07 GMT", rule-id="Expiration1Days"',
LastModified: 2022-09-05T15:03:07.000Z,
// other log....
why my file with prefix “other-prefix” expiration with id “Expiration1Days” ?
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Heya, @misbahanemone
DigitalOcean Spaces lifecycle rules can be confusing here because Spaces is S3-compatible but not 100% S3 feature-complete, and prefix filtering doesn’t always behave like AWS S3.
In your specific test, the important detail is this: the Expiration you see in the GetObject response is not proof the object will actually be deleted by that rule, it’s just telling you what lifecycle rule the server thinks applies (or is attaching by default). In Spaces, it’s fairly common to see the same rule-id show up even when you expect the prefix filter to exclude it.
What to do instead:
Verify by behavior, not headers
Create two objects: one under oneday/ and one under other-prefix/, then wait >24h and see what actually gets deleted. That’s the only reliable way to confirm what Spaces is enforcing.
Use separate rules carefully (or separate buckets)
If you need strict “only this folder expires”, the most reliable approach on Spaces is often separate buckets (e.g. maxchat-oneday vs maxchat-longterm) instead of relying on prefix filters.
Try the older style Prefix (no Filter block) if you want to test compatibility
Some S3-compatible providers behave better with the legacy Prefix field than with Filter.Prefix. If your SDK allows it, test that variant (same rule, just expressed differently) and re-check after a day.
Bottom line: you’re not crazy — this is a known kind of “S3-compat edge” with Spaces. If you need guaranteed separation by prefix, I’d strongly consider bucket separation as the practical fix.
Hope that this helps!
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.