Joint session with Vercel: How to build intelligent storefronts (May 15th)

Sanity image upload error: "Invalid image, could not read metadata

1 replyLast updated: Nov 29, 2025

• OK It turns out that, I was sending the BLOB via URL to the function and that was the problem. Leaving the code here in case someone gets the same err.Hello, I am trying to upload an image with javascript client but getting the following error. Anybody gets the same error before? The blob is the File object where I get from react dropzone.


{
    "response": {
        "body": {
            "statusCode": 400,
            "error": "Bad Request",
            "message": "Invalid image, could not read metadata",
            "details": "Input buffer contains unsupported image format"
        },
        "url": "<https://xx.api.sanity.io/v2022-03-10/assets/images/production?filename=634ff16fea978807370a020d>",
        "method": "POST",
        "headers": {
            "content-length": "150",
            "content-type": "application/json; charset=utf-8",
            "etag": "W/\"96-wI2AUJgOZsmnCanyui4zXBV3NKg\""
        },
        "statusCode": 400,
        "statusMessage": ""
    },
    "statusCode": 400,
    "responseBody": "{\n  \"statusCode\": 400,\n  \"error\": \"Bad Request\",\n  \"message\": \"Invalid image, could not read metadata\",\n  \"details\": \"Input buffer contains unsupported image format\"\n}"
}

export async function uploadImageBlob(blob: File, fileName: string) {

    console.log(blob)

    client.assets.upload('image', blob, { contentType: 'image/jpeg', filename: fileName })
        .then(() =&gt; { console.log('upload success')})
        .catch((err) =&gt; { console.log(err)});

}
AI Update

This is a common issue when uploading images with the Sanity JavaScript client! The error "Invalid image, could not read metadata" typically occurs when you're passing a URL or incorrect data format to client.assets.upload() instead of the actual file data.

As you discovered, the problem was sending the BLOB via URL to the function. The Sanity client expects the actual File object or binary data, not a blob URL string created with URL.createObjectURL().

Here's the corrected approach:

export async function uploadImageBlob(blob: File, fileName: string) {
    try {
        // Pass the File object directly - NOT a URL
        const result = await client.assets.upload('image', blob, { 
            contentType: blob.type || 'image/jpeg', // Use the actual file type
            filename: fileName 
        });
        
        console.log('Upload success:', result);
        return result;
    } catch (err) {
        console.error('Upload error:', err);
        throw err;
    }
}

Common causes of this error:

Working example with React Dropzone:

import { useDropzone } from 'react-dropzone';
import { client } from './sanityClient';

function ImageUploader() {
    const onDrop = async (acceptedFiles: File[]) => {
        const file = acceptedFiles[0];
        
        try {
            // Pass the File object directly - NOT a URL
            const asset = await client.assets.upload('image', file, {
                contentType: file.type,
                filename: file.name
            });
            
            console.log('Uploaded asset:', asset);
        } catch (error) {
            console.error('Upload failed:', error);
        }
    };
    
    const { getRootProps, getInputProps } = useDropzone({ 
        onDrop,
        accept: {
            'image/*': ['.jpeg', '.jpg', '.png', '.gif', '.webp']
        }
    });
    
    return (
        <div {...getRootProps()}>
            <input {...getInputProps()} />
            <p>Drop an image here</p>
        </div>
    );
}

The key takeaway: never convert the File to a URL before passing it to client.assets.upload(). The method expects the raw file data, which the File object from React Dropzone provides directly. Thanks for sharing your solution - it'll definitely help others who encounter this same error!

Show original thread
1 reply

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Related contributions