remotion-dev/remotion · error
could not cancel render %q: %w
Error message
could not cancel render %q: %w
What it means
Go client error from cancelRenderOnLambda: the final PutObject that writes the cancellation signal (renders/<renderId>/cancel.json with a cancelledAt timestamp) failed; the S3 error is wrapped with %w. The read path succeeded, so this points at write permissions, bucket state, or transport issues.
Source
Thrown at packages/lambda-go/s3.go:116
if err := json.Unmarshal(progressBody, &progress); err != nil {
return fmt.Errorf("could not parse progress for render %q: %w", input.RenderId, err)
}
if !progress.CancellationEnabled {
return fmt.Errorf("cannot cancel render %s: the render was not started with enableCancellation: true", input.RenderId)
}
cancellationBody, err := json.Marshal(map[string]int64{"cancelledAt": time.Now().UnixMilli()})
if err != nil {
return fmt.Errorf("could not serialize cancellation signal: %w", err)
}
_, err = client.PutObject(context.TODO(), &s3.PutObjectInput{
Bucket: new(input.BucketName),
Key: new(cancellationKey(input.RenderId)),
Body: strings.NewReader(string(cancellationBody)),
ContentType: new("application/json"),
})
if err != nil {
return fmt.Errorf("could not cancel render %q: %w", input.RenderId, err)
}
return nil
}
// newS3Client creates an S3 client using the same shared config resolution as
// the Lambda client in invocations.go.
func newS3Client(region string, forcePathStyle bool) (*s3.Client, error) {
awsConfig, err := config.LoadDefaultConfig(
context.TODO(),
config.WithRegion(region),
)
if err != nil {
return nil, fmt.Errorf("could not load AWS config: %w", err)
}
return s3.NewFromConfig(awsConfig, func(options *s3.Options) {
options.UsePathStyle = forcePathStyle
}), nilView on GitHub (pinned to 10db9de073)
Solutions
- Unwrap the error to the smithy APIError — AccessDenied means adding s3:PutObject on renders/* to the caller's policy.
- Verify the bucket still exists and the region/endpoint in the client matches the bucket's region.
- Retry once for transient throttling (SlowDown) with backoff.
Defensive patterns
Strategy: retry
Type guard
func isS3WriteDenied(err error) bool {
var apiErr smithy.APIError
return errors.As(err, &apiErr) && apiErr.ErrorCode() == "AccessDenied"
} Try / catch
if err := client.CancelRenderOnLambda(ctx, input); err != nil {
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
switch apiErr.ErrorCode() {
case "AccessDenied": // fix IAM: add s3:PutObject on renders/*
case "SlowDown": // retry with backoff
default: return err
}
}
} Prevention
- Grant cancelling roles both s3:GetObject and s3:PutObject on renders/* in the render bucket.
- Verify bucket region matches the client's configured region before operations.
- Retry PutObject-path failures once with backoff for throttling.
When it happens
Trigger: The caller has s3:GetObject but not s3:PutObject on the bucket; bucket deleted mid-flight; network failure during upload; wrong region endpoint for the bucket.
Common situations: IAM policies that only grant read for monitoring; least-privilege service roles missing the write statement for renders/*; S3 outage or throttling.
Related errors
- could not read progress for render %q: %w
- could not parse progress for render %q: %w
- 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@10db9de073 (2026-08-22).
Data as JSON: /api/errors/2f51f12faa097036.
Report an issue: GitHub.