{"record":{"id":"927cd4ff0f82b811","repo":"remotion-dev/remotion","slug":"you-don-t-have-the-required-permissions-to-delete","errorCode":null,"errorMessage":"You don't have the required permissions to delete lifecycle rules on the bucket \"${bucketName}\", but the \"enableFolderExpiry\" option was set to \"false\". Ensure that your user has the \"s3:PutLifecycleConfiguration\" permission. Set \"enableFolderExpiry\" to \"null\" to not overwrite any existing lifecycle rules.","messagePattern":"You don't have the required permissions to delete lifecycle rules on the bucket \"(.+?)\", but the \"enableFolderExpiry\" option was set to \"false\"\\. Ensure that your user has the \"s3:PutLifecycleConfiguration\" permission\\. Set \"enableFolderExpiry\" to \"null\" to not overwrite any existing lifecycle rules\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lambda-client/src/lifecycle-rules.ts","lineNumber":76,"sourceCode":"\tbucketName: string;\n\tregion: AwsRegion;\n\tcustomCredentials: CustomCredentials<AwsProvider> | null;\n\tforcePathStyle: boolean;\n\trequestHandler: RequestHandler | null;\n}) => {\n\tconst deleteCommandInput = deleteLifeCycleInput({\n\t\tbucketName,\n\t});\n\ttry {\n\t\tawait getS3Client({\n\t\t\tregion,\n\t\t\tcustomCredentials,\n\t\t\tforcePathStyle,\n\t\t\trequestHandler,\n\t\t}).send(new DeleteBucketLifecycleCommand(deleteCommandInput));\n\t} catch (err) {\n\t\tif ((err as Error).stack?.includes('AccessDenied')) {\n\t\t\tthrow new Error(\n\t\t\t\t`You don't have the required permissions to delete lifecycle rules on the bucket \"${bucketName}\", but the \"enableFolderExpiry\" option was set to \"false\". Ensure that your user has the \"s3:PutLifecycleConfiguration\" permission. Set \"enableFolderExpiry\" to \"null\" to not overwrite any existing lifecycle rules.`,\n\t\t\t);\n\t\t}\n\t}\n};\n\nexport async function applyLifeCyleOperation({\n\tenableFolderExpiry,\n\tbucketName,\n\tregion,\n\tcustomCredentials,\n\tforcePathStyle,\n\trequestHandler,\n}: {\n\tenableFolderExpiry: boolean | null;\n\tbucketName: string;\n\tregion: AwsRegion;\n\tcustomCredentials: CustomCredentials<AwsProvider> | null;","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/lambda-client/src/lifecycle-rules.ts#L58-L94","documentation":"Thrown when applyLifeCyleOperation tries to DELETE the bucket's lifecycle configuration (because enableFolderExpiry was explicitly set to false) and S3 responds with AccessDenied. Deleting lifecycle rules requires the s3:PutLifecycleConfiguration IAM permission, not just read access. The error is a deliberate re-throw that translates the raw AccessDenied into actionable guidance.","triggerScenarios":"Calling any code path that invokes applyLifeCyleOperation with enableFolderExpiry===false while the configured AWS credentials lack s3:PutLifecycleConfiguration. The delete is attempted via DeleteBucketLifecycleCommand; when err.stack contains 'AccessDenied', this message replaces it.","commonSituations":"Minimal IAM policies used for cost-sensitive deployments; CI roles scoped to only what rendering needs; using a read-only or render-only role when calling deploySite/deployFunction that also normalizes lifecycle rules; switching enableFolderExpiry from null/true to false to clean up rules.","solutions":["Set enableFolderExpiry to null instead of false to skip lifecycle rule overwrites entirely.","Add the s3:PutLifecycleConfiguration permission to the IAM user/role running the operation (on the specific bucket ARN).","Run the lifecycle cleanup once with a privileged admin role, then return to the restricted role with enableFolderExpiry=null.","Verify the bucket name is correct and belongs to the account whose credentials you are using."],"exampleFix":"// before\nawait renderMediaOnLambda({ ...opts, enableFolderExpiry: false });\n\n// after (skip lifecycle overwrites)\nawait renderMediaOnLambda({ ...opts, enableFolderExpiry: null });\n\n// or grant IAM:\n// { Effect: 'Allow', Action: 's3:PutLifecycleConfiguration', Resource: 'arn:aws:s3:::YOUR-BUCKET' }","handlingStrategy":"validation","validationCode":"// Decide enableFolderExpiry based on the IAM capabilities of the runtime role\nconst canManageLifecycle = await hasPermission('s3:PutLifecycleConfiguration');\nconst enableFolderExpiry = canManageLifecycle ? false : null; // null = do not touch","typeGuard":null,"tryCatchPattern":"try {\n  await renderMediaOnLambda({ ...opts, enableFolderExpiry: false });\n} catch (e) {\n  if (e instanceof Error && /s3:PutLifecycleConfiguration/.test(e.message)) {\n    // retry without overwriting lifecycle rules\n    await renderMediaOnLambda({ ...opts, enableFolderExpiry: null });\n  } else { throw e; }\n}","preventionTips":["Audit your IAM policy for s3:PutLifecycleConfiguration before setting enableFolderExpiry to false.","Prefer enableFolderExpiry=null in CI roles that should not mutate bucket configuration.","Document which roles are allowed to manage lifecycle rules."],"tags":["aws","iam","s3","lifecycle","permissions"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}