Hello Siti Omar,
When objects fail to transition to Glacier after 90 days, even though the lifecycle rule appears enabled, it usually points to either versioning changes or hidden conditions in the policy evaluation. Since you mentioned recently enabling bucket versioning, note that lifecycle rules apply differently to current and noncurrent object versions, so you may need to explicitly configure transitions for both.
The first step is to double-check the lifecycle configuration XML/JSON and confirm that the rule scope includes current versions. If versioning was turned on after the rule was created, the policy may only be applying to noncurrent versions. You can use the AWS CLI command aws s3api get-bucket-lifecycle-configuration to verify the exact rules being applied. Next, review CloudTrail for PutLifecycleConfiguration events to ensure no silent changes occurred.
To debug execution, enable S3 Lifecycle logging by checking the object’s status with aws s3api head-object and confirm whether the transition date is being calculated. If the transition is scheduled but not executed, check whether Glacier is blocked by bucket policies or KMS encryption settings. Sometimes, restrictive bucket policies prevent transition actions even if the lifecycle rule is valid.
As a best practice, test with a small bucket and a simplified lifecycle rule to confirm transitions work, then replicate the configuration to production. This helps isolate whether the issue is rule syntax, versioning, or policy conflicts.
I hope the response provided some helpful insight. If you find this answer useful, please hit “accept answer” so I know it addressed your concern.
Jason