Image upload from API route on cloudinary works on localhost but not on vercel production
While the above route works perfectly fine while uploading files running on localhost, when i push to vercel it the AXIOS request will get a strange "405 Method Not Allowed" error while on vercel logs "Unknown application error occurred Runtime.Unknown"
export async function POST(req: Request) { try { const formData = await req.formData(); const banner = formData.get("banner") as File; const arrayBuffer = await banner.arrayBuffer(); const buffer = new Uint8Array(arrayBuffer); const results: any = await new Promise((resolve, reject) => { cloudinary.uploader .upload_stream( { folder: "demo", }, function (error, result) { if (error) { reject(error); return; } resolve(result); } ) .end(buffer); }); const { secure_url } = results; return NextResponse.json({ data: secure_url }); } catch (error) { console.error(error); return NextResponse.json( { message: "An error occurred while processing the request.", }, { status: 500 } ); } }
Answers
-
Hey there! Thanks for getting in touch
The Next package is actually a community developed library. This library is developed, tested, and maintained by the community, which means we don’t directly support it and so we can’t guarantee that PRs/issues on those repos will get the attention you may expect.
I'm afraid, in this instance, we won't be able to provide specific troubleshooting or diagnostic information. Instead, I would suggest you reach out to the developer either via Github or Twitter. Links for both can be found here: https://www.npmjs.com/package/next-cloudinary#%EF%B8%8F-community--support
Alternatively, as things work locally but not on Vercel, you may want to try the Vercel community over at https://vercel.com/help#issues
I hope this helps. Please let me know if you have any further questions.
Best regards,
-Danny
0 -
I don't use next-cloudinary but
import { v2 as cloudinary } from "cloudinary";
cloudinary.uploader.upload_stream()
as you can tell by the code i've provided
thanks for your answer anyway
0 -
My apologies! I saw the usage of
NextResponse.json
and overlookedupload_stream()
. Vercel's support staff will probably be best-placed to advise here, but if you let me know your cloud name, I can see if there is anything on our internal logging that may point to a root-cause for your problem.Thanks,
-Danny
0 -
there you go
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME="dmz4yyl6i"
however since it works on localhost i quess theres some kind of vercel incompatibility with the way i am handling the upload process with your SDK
0 -
Thanks.
I've had a look and I see that we're seeing errors of "ArgumentError: invalid byte sequence in UTF-8" since October 31st 2023, 20:51:09 (UTC). What's interesting is our logging shows the file is being appended to the API key.
It may be worth checking exactly how the application is sending the data when deployed to Vercel. Perhaps using something like POSTing to webhook.site or similar both on and off of Vercel and see how they compare.
Kind regards,
-Danny
1 -
Thanks for your asnwer.
https://webhook.site/#!/2c531c9b-126a-427e-ab3c-7d938f81e035/
I don't really see any differece that should cause this. I ll dig more into it
0 -
an update with the vercel's logs
(node:8) ExperimentalWarning: buffer.File is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Unhandled Promise Rejection {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"[object Object]","reason":{"message":"Server return invalid JSON response. Status Code 500. SyntaxError: Unexpected token < in JSON at position 0","name":"Error","http_code":500},"promise":{"exception":{"message":"Server return invalid JSON response. Status Code 500. SyntaxError: Unexpected token < in JSON at position 0","name":"Error","http_code":500}},"stack":["Runtime.UnhandledPromiseRejection: [object Object]"," at process.<anonymous> (file:///var/runtime/index.mjs:1276:17)"," at process.emit (node:events:529:35)"," at /var/task/.next/server/chunks/9636.js:38:8381"," at runSingle (/var/task/.next/server/chunks/9636.js:38:451)"," at flush (/var/task/.next/server/chunks/9636.js:38:397)"," at process.processTicksAndRejections (node:internal/process/task_queues:77:11)"]}
Unknown application error occurred
Runtime.Unknown
0 -
{
message: 'Server return invalid JSON response. Status Code 500. SyntaxError: Unexpected token < in JSON at position 0',
name: 'Error',
http_code: 500
}
0 -
@vnvm - Some ideas for you!
Check Encoding: The "invalid byte sequence in UTF-8" error suggests there may be an issue with character encoding. Ensure that the data you're sending to Cloudinary is encoded in UTF-8. Check your file encoding, especially if you're working with non-ASCII characters.
Verify Environment Variables: Confirm that your environment variables are correctly set both locally and on Vercel. The
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME
variable should be set correctly in your Vercel environment.Network Differences: Since the issue occurs on Vercel but not locally, consider differences in network environments. Ensure that Vercel allows the necessary outbound connections to Cloudinary. Check for any firewall or network restrictions that might affect the communication between your application and Cloudinary's API.
Review Error Logs: The error message indicates "SyntaxError: Unexpected token < in JSON at position 0." This often suggests that the response from the server is not valid JSON. Review the response from the Cloudinary API and ensure it is properly formatted JSON.
Node.js Version: The warning about the experimental feature "buffer.File" suggests that you are using an experimental feature in Node.js. Make sure that your Node.js version is compatible with the libraries and features you are using. Consider using a more stable version if necessary. https://nodejs.org/en/download
Contact Vercel Support: If you're unable to resolve the issue, it might be beneficial to reach out to Vercel support for assistance, especially since the issue occurs on their platform. https://vercel.com/contact
0 -
Thanks for the hints.
I've seen more people reporting this, so its not only me
Vercels support will not reply if not on a paid plan, and their community is not helpful at all.
the promise is being rejected with the following error which is not explanoty at all,
{
message: 'Server return invalid JSON response. Status Code 500. SyntaxError: Unexpected token < in JSON at position 0',
name: 'Error',
http_code: 500
}
and results are undefiend
i've checked the parsed data and they are identicall to the ones provided while on localhost, i really have no idea why this could be happening
the request seems to leave vercel, but cloudinary returns wrong bad response for some reason
0 -
@vnvm Using the SDK method
upload_stream
, there is an unhandled error when the method is invoked in abuild
NextJS environment. An error HTML page is being received as a response instead of a JSON data format, hence, the error HTTP 500 is raised.As an alternative to the use of
upload_stream
, the `upload` method of the Node SDK together with a Data URI can be used, for example:import { v2 as cloudinary } from "cloudinary"; import { NextResponse } from "next/server"; // Cloudinary config cloudinary.config({ cloud_name: "your_cloud_name", api_key: "your_api_key", api_secret: "your_api_secret", secure: true, }); export const POST = async (req) => { const data = await req.formData(); const image = await data.get("image"); const fileBuffer = await image.arrayBuffer(); var mime = image.type; var encoding = 'base64'; var base64Data = Buffer.from(fileBuffer).toString('base64'); var fileUri = 'data:' + mime + ';' + encoding + ',' + base64Data; try { const uploadToCloudinary = () => { return new Promise((resolve, reject) => { var result = cloudinary.uploader.upload(fileUri, { invalidate: true }) .then((result) => { console.log(result); resolve(result); }) .catch((error) => { console.log(error); reject(error); }); }); }; const result = await uploadToCloudinary(); let imageUrl = result.secure_url; return NextResponse.json( { success: true, imageUrl: imageUrl }, { status: 200 } ); } catch (error) { console.log("server err", error); return NextResponse.json({ err: "Internal Server Error" }, { status: 500 }); } };
Hope this helps.
1