8 – Retrieve an image field’s file path to upload file programatically to S3

I recently implemented an S3 Bucket to store images, however doing so caused some strange behavior.


In the File System configurations I changed the Default download method to Amazon Simple Storage Service. The public and private file systems I did not change (still under sites/default/).

In the S3FS configurations, I set up my s3 bucket and set the public folder setting to public and private folder to private, leaving the root folder blank. In my s3 bucket I have a public and private folder at the root.

I have a content-type with an image field whose File Directory is set to images.


I have this chunk of code that creates/updates those nodes with a field that downloads an image from a url. This is how I set the image

$image_url = $data('img_url'); // returns something like https://somesite.com/image/sampleimage.jpg
$file = system_retrieve_file($image_url, 'public://images/', TRUE, FileSystemInterface::EXISTS_REPLACE);
if ($file && $file->id()) {
    $course_node->set('field_image', (
        'target_id' => $file->id(),
        'alt' => $titles(0),


BEFORE I implemented the S3FS related changes, this worked fine. I could upload an image through the admin portal OR add some through the code above, and images would be uploaded to sites/default/files/course_images.

AFTER I implemented the S3FS related changes I am having different results:

  • When uploading an image through the admin portal, the image gets uploaded in my s3 bucket in the folder s3root:images/ with the correct file name.
  • When uploading an image via the code, the image gets uploaded in my s3 bucket as the file s3root:public/images

I would like both to upload to just public/images, however I’m more concerned with the chunk of code uploading the file to s3 under the file s3:root:public/images instead of storing it in the folder s3root:public/images/ with the name same as what it was from the original image url.

What is incorrect about system_retrieve_file that is causing it not to play nice with S3?