remotion-dev/remotion · error · Error
Unable to access item "${objectKey}" from bucket "${bucketNa
Error message
Unable to access item "${objectKey}" from bucket "${bucketName}". You must have permission for both "s3:GetObject" and "s3:ListBucket" actions. What it means
Thrown by presign-url when generating a pre-signed GET URL fails with an unknown error or HTTP 403. S3 returns 403 for missing permissions; a 403 on presigning indicates the credentials are not allowed both s3:GetObject (for the object) and s3:ListBucket (on the bucket) — AWS requires both to validate the object's existence for a presigned download.
Source
Thrown at packages/lambda-client/src/presign-url.ts:76
if (checkIfObjectExists === true) {
try {
await s3Client.send(
new HeadObjectCommand({
Bucket: bucketName,
Key: objectKey,
}),
);
} catch (err) {
if ((err as {name: string}).name === 'NotFound') {
return null as unknown as string;
}
if (
(err as Error).message === 'UnknownError' ||
(err as {$metadata: {httpStatusCode: number}}).$metadata
.httpStatusCode === 403
) {
throw new Error(
`Unable to access item "${objectKey}" from bucket "${bucketName}". You must have permission for both "s3:GetObject" and "s3:ListBucket" actions.`,
);
}
throw err;
}
}
const objCommand = new GetObjectCommand({
Bucket: bucketName,
Key: objectKey,
});
const publicUrl = await getSignedUrl(s3Client, objCommand, {
expiresIn: expiresInSeconds,
});
return publicUrl;View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Grant both s3:GetObject on the object ARN and s3:ListBucket on the bucket ARN to the IAM principal.
- If using a bucket policy, ensure ListBucket covers the prefix of objectKey.
- Confirm the credentials in use belong to the account that owns the bucket.
- Check CloudTrail/S3 access logs for the underlying 403 reason if the policy looks correct.
Example fix
// before: only GetObject
// { Effect: 'Allow', Action: ['s3:GetObject'], Resource: 'arn:aws:s3:::bucket/*' }
// after: both required actions
// [
// { Effect: 'Allow', Action: ['s3:GetObject'], Resource: 'arn:aws:s3:::bucket/*' },
// { Effect: 'Allow', Action: ['s3:ListBucket'], Resource: 'arn:aws:s3:::bucket' }
// ] Defensive patterns
Strategy: validation
Validate before calling
// Pre-check that the role can both GetObject and ListBucket before presigning
await s3.send(new GetObjectCommand({ Bucket: bucketName, Key: objectKey }));
await s3.send(new ListObjectsV2Command({ Bucket: bucketName, Prefix: prefix, MaxKeys: 1 })); Try / catch
try {
const url = await presignUrl({ bucketName, objectKey, ... });
} catch (e) {
if (e instanceof Error && /s3:GetObject.*s3:ListBucket/.test(e.message)) {
// alert ops to fix IAM; do not retry until policy updated
}
throw e;
} Prevention
- Always grant s3:GetObject on object ARNs AND s3:ListBucket on the bucket ARN together.
- For presigned URLs, ensure ListBucket covers the object's prefix.
- Validate IAM with a dry-run GetObject before relying on presigning in production.
When it happens
Trigger: The presigning HEAD/getObject probe catches an error whose message is 'UnknownError' or whose $metadata.httpStatusCode is 403, and re-throws this guidance message. (A NotFound error instead returns null.)
Common situations: Rendering with a service role whose policy only grants s3:GetObject but not s3:ListBucket; bucket policy restricting ListBucket to specific prefixes; using credentials from a different account; encryption/KMS misconfiguration surfacing as UnknownError.
Related errors
- Since April 2023, more AWS permissions are required to creat
- PARTIAL SUCCESS: The s3:PutBucketOwnershipControls was found
- You don't have the required permissions to create lifecycle
- You don't have the required permissions to delete lifecycle
- Bucket owner mismatch: Expected the bucket ${bucketName} to
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/3becfb38478c181a.
Report an issue: GitHub.