This is my first time posting a StackExchange question, so thanks in advance for your patience.

We are attempting to upload an image to a headless Drupal application using the File Upload REST resource. In testing the endpoint with Postman, we've run into a weird issue. We are able to target the endpoint and upload an image fine through Postman's 'binary' body type, in which you just attach an image to the GUI and it does the rest for you. But if we use the 'raw' body type and pass in the Base64 code for the image, the image entity is created but the actual appears broken in Drupal. According to the linked documentation, it appears the binary data just needs to be passed in directly with the appropriate headers.

So my questions are: Is there a specific way to format or package Base64 image information to upload directly to Drupal? Am I falsely equating Base64 and binary data? Does anyone have any similar experience? Thanks a ton for taking a second to read this.

For context:

Our endpoint in both cases is http://localhost:8000/file/upload/{entity_type_id}/{bundle}/{field_name}?_format=json

And our headers are:

Content-Disposition: file;filename="test.jpg"
Content-Type: application/octet-stream

And when we attempt to preview the image in Drupal after passing the Base64 directly, this is what the preview looks like (an ominous white outlined square on a black background):

White square on black background


Recently I have faced the same issue in a file upload. For this, I have done base64_decode() before the file_save_data() in Drupal. Example code:

  if (isset($file_data['title']) && isset($file_data['data'])) {
      // Get base64_encode of file data and explode to get data.
      $encodedImgString = explode(',', $file_data['data'], 2)[1];
      // Decode the data.
      $decodedImgString = base64_decode($encodedImgString);
      // Get the file name.
      $file_name = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file_data['title']);*/
      // Save the file using base_decode() data.
      $file = file_save_data($decodedImgString, 'public://' . $file_data['title'], FILE_EXISTS_RENAME);
      $file_result = [
        'target_id' => $file->id(),
        'title' => $file_data['title'],

Hope this helps you.

Note: Here I have used custom REST API for file uploads.

  • Thanks for the response! I'll give this a shot and follow up – Kevin May 9 '19 at 11:34
  • Worked like a charm, I created a custom endpoint and used this method. I owe you one! – Kevin May 9 '19 at 15:01
  • is it mandatory to give filename in the Content-disposition header? cant we get it from the uploaded file ? – Suraj Jul 22 '20 at 12:28

I was stuck with the same issue, there are lots of posts saying that we should send the image content as base64 i.e.

    "filename": [
            "value": "image.jpg"
    "data": [
            "value": "base64encoded image string"

When I inspected the image on the destination site, I could see a square, just like reported in this thread. I openeded the file into a binary editor and the contents of the file were the array sent.

After struggling a lot, I figured how to make this work by sending the actual content of the image i.e.


    $curlHandler = curl_init();
    curl_setopt_array($curlHandler, [
      CURLOPT_URL => 'http://admin:password@site.local/file/upload/node/page/field_image',
        'Authorization: Basic ' . base64_encode('admin:password'),
        'Content-Type: application/octet-stream',
        'Content-Disposition: file; filename="image.jpg"',
      CURLOPT_POSTFIELDS => file_get_contents('./image.jpg'),
    $response = curl_exec($curlHandler);

This worked and allowed me to use the built in endpoint for /file/upload/node/{type}/{field_name} with no need to write custom code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.