Persistent 404 NOT_FOUND on Successfully Deployed Serverless Function (Node.js)
Hello Vercel Community,
I’m encountering a very persistent and frustrating issue with a serverless function (api/get-appointment-types.js) in my project, online-afspraken-systeem. Despite repeated successful deployments, the function’s endpoint consistently returns a 404: NOT_FOUND error. I’ve exhausted all troubleshooting steps I can think of, and I’m hoping someone here might have insights.
Project Overview: I’m trying to create a simple Node.js serverless function that acts as an API endpoint, calling an external third-party API (agenda.onlineafspraken.nl/APIREST).
The Problem: After every deployment, the Vercel CLI reports ✅ Production: [URL] and the build logs show “Build Completed” with no critical errors. However, when I try to access the function’s URL, I get a 404: NOT_FOUND error.
Key Troubleshooting Steps Already Taken:
- Deployment URL Confirmed: I’m using the exact production URL provided by Vercel.
vercel.jsonConfiguration: I’ve tried multiple configurations, including specific and catch-all routes, and verified the file path. The currentvercel.jsonis:JSON{ "version": 2, "builds": [ { "src": "api/get-appointment-types.js", "use": "@vercel/node" } ], "routes": [ { "src": "/api/get-appointment-types", "dest": "/api/get-appointment-types.js" } ] }- File Location: The
get-appointment-types.jsfile is correctly located in theapi/directory in the root of my project. - Environment Variables:
ONLINE_AFSPRAKEN_API_KEYandONLINE_AFSPRAKEN_API_SECRETare correctly set in the Vercel project settings for the Production environment. - Build Logs: Consistently show “Build Completed” successfully.
- Runtime Logs: Unfortunately, since it’s a
404, the function isn’t even invoked, so there are no specific runtime error logs to provide beyond the404: NOT_FOUNDitself.
Most Recent Failing Deployment Details:
- Deployment ID:
fra1::jp6fp-1752088431027-1153cc7be122(this is the most recent I encountered) - Affected URL:
https://online-afspraken-systeem-dnbb3zgku-masiras-projects.vercel.app/api/get-appointment-types
api/get-appointment-types.js Code Content:
`// api/get-appointment-types.js
import axios from ‘axios’;
import CryptoJS from ‘crypto-js’;
export default async function handler(req, res) {
if (req.method !== ‘POST’) {
return res.status(405).json({ error: ‘Method Not Allowed’, message: ‘Only POST requests are accepted.’ });
}
try {
const ONLINE_AFSPRAKEN_API_KEY = process.env.ONLINE_AFSPRAKEN_API_KEY;
const ONLINE_AFSPRAKEN_API_SECRET = process.env.ONLINE_AFSPRAKEN_API_SECRET;
if (!ONLINE_AFSPRAKEN_API_KEY || !ONLINE_AFSPRAKEN_API_SECRET) {
console.error("Missing API Key or Secret in environment variables.");
return res.status(500).json({ error: 'Server Configuration Error', message: 'API Key or Secret is missing. Please check Vercel Environment Variables.' });
}
const API_URL = "https://agenda.onlineafspraken.nl/APIREST";
const HTTP_METHOD = "POST";
const apiSalt = Math.floor(Date.now() / 1000);
const paramsForSigning = {
method: "getAppointmentType",
};
const sortedKeys = Object.keys(paramsForSigning).sort();
let stringToSign = "";
for (const key of sortedKeys) {
stringToSign += key + paramsForSigning[key];
}
stringToSign += ONLINE_AFSPRAKEN_API_SECRET;
stringToSign += apiSalt.toString();
const apiSignature = CryptoJS.SHA256(stringToSign).toString();
const requestBody = new URLSearchParams();
for (const key in paramsForSigning) {
if (Object.prototype.hasOwnProperty.call(paramsForSigning, key)) {
requestBody.append(key, paramsForSigning[key]);
}
}
requestBody.append('api_salt', apiSalt.toString());
requestBody.append('api_signature', apiSignature);
const response = await axios.post(API_URL, requestBody.toString(), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': '*/*',
},
});
res.setHeader('Content-Type', 'application/xml');
res.status(200).send(response.data);
} catch (error) {
console.error("Error calling OnlineAfspraken API:", error.message);
if (error.response) {
console.error("API Response Data:", error.response.data);
console.error("API Response Status:", error.response.status);
console.error("API Response Headers:", error.response.headers);
res.status(error.response.status).send(error.response.data);
} else if (error.request) {
console.error("No response received from API:", error.request);
res.status(500).json({ error: 'No response from API', message: 'The request was made but no response was received from the OnlineAfspraken API.' });
} else {
console.error("Request setup error:", error.message);
res.status(500).json({ error: 'Internal Server Error', message: 'An unexpected error occurred: ' + error.message });
}
}
}`
Any help or suggestions from the community would be greatly appreciated! Thank you in advance.
