Post to edge function path return 404

I have three edge functions, 1 for theme toggling for dark and light mode and one for OG(Open graph) and the third edge function is to send email via nodemailer to my email for a contact form on the site.
The first two are working great in fact has been for almost a year the new edge function was just added and it return 404 but the other two still working. I’ve debug to see what the issue is what I discovered is that the request is not reaching the server at all common console at the top of the function won’t log
I’m using fetch to post the form data from the browser and have a edge function that respond to the request. Below is my “toml configuration” and I can provide my front-end code and the back-end edge function code

  function = "og"
  path = "/og"

  function = "theme-toggle"
  path = "/theme-toggle"

  function = "theme-toggle"
  path = "/*/theme-toggle"

  function = "theme-toggle"
  path = "/*"
  function = "contact-form"
  path = "/*/contact-form"

  function = "contact-form"
  path = "/contact-form"

  function = "contact-form"
  path = "/contact/contact-form"

  for = "/*"
    X-Frame-Options = "SAMEORIGIN"
    X-Content-Type-Options = "nosniff"
    X-XSS-Protection = "1; mode=block"

Hey there!

Not sure how to troubleshoot that for you, but why not use the built-in form functionality from Netlify?

The Setup is pretty simple and removes a lot of complexity and deliverability issues.

Sure it allows only 100 form submissions (on the $0/ month plan) and when you leverage the spam prevention tools available, those 100 submissions should be quality contacts.

More on Billing and Usage for Forms is available at Forms usage and billing | Netlify Docs


Hey @dr3apap! The configuration looks good for what you’re trying to do, i’m unsure what’s going on here. There’s probably something else going wrong somewhere :slight_smile:
Could you provide something like a reproduction repository that contains the unexpected behaviour, that I can use to debug this locally?

Yes sure. I just don’t want to push a broken code upstream because my build is from the repository is from Github. I can provide the edge function code and the front end code that is making the request.

export default async (request) => {
    console.log(`Is this the nodemailer:${nodemailer}`);
    const formData = await request.json();
    const transporter = nodemailer.createTransport({
  host: '',
  port: 2525,
  auth: {
    user: <UserId>,
    pass: <Password>,

// async..await is not allowed in global scope, must use a wrapper
async function main() {
  // send mail with defined transport object
  const info = await transporter.sendMail({
    from:, // sender address
    to: '', // list of receivers
    subject:formData.purpose, // Subject line
    text: formData.fullname, // plain text body
    html: `<b>${FormData.message}</b>`, // html body

  console.log('Message sent: %s', info)

    return new Response('E-mail sent successfully', {

} catch(err){
    return new Response('Fail to send email', {

function processContactData(){
 const contactForm = document.querySelector('#contact');
 const contactFormCta = document.querySelector('.contact--cta');
 const url = contactForm.action;
 let response
 async function processForm(contactData) {
  response = await fetch(url,contactData);
  console.log(`This is the response: ${response}`);

 contactForm.addEventListener('submit', (e) => {
    const contactData = new FormData(contactForm, contactFormCta);
    // const body = {
    //     fullname:contactData.get('fullname'),
    //     email:contactData.get('email'),
    //     company:contactData.get('company'),
    //     purpose:contactData.get('fulltime') && 'fulltime' || contactData.get('parttime') && 'parttime' || contactData.get('contract') && 'contract' || contactData.get('other') && 'other',
    //     message:contactData.get('message'),
    //     };

    const contactPayload = {
        body:new URLSearchParams(contactData),


            // const feedBack = document.createElement('p');
            // if(response.status == '200' || response.status == '201'){
            // = 'text-text-fluid--2 text-text-1 bg-surface-2';
            //     feedBack.textContent('Thank you for contacing me. Looking forward to working with you!');
            //     contactFormCta.insertAdjacentElement('afterend', feedBack);
            //     contactForm.reset();
            // } else{
            // = 'text-text-fluid--2 text-text-1 bg-surface-2';
            //     feedBack.textContent('Sorry something went wrong, please submit the form again');
            //     contactFormCta.insertAdjacentElement('afterend', feedBack);
            // }

document.addEventListener('DOMContentLoaded', processContactData);

The commented code are just different iterations and prototyping structure they shouldn’t be a problem.

My observation is the request is not reaching the server the edge function never get run, There is a console.log() statement at the top of the edge function that never get call. I’m using Astro with Netlify adapter and I’m running Netlify cli in dev mode.

The issue is I need the formData to be send to an email. I’m not sure how this will happen if there is no provided logic for server less or edge function. What path will the form be posted to and what happen to the form data? Kindly elaborate I went through the setup but still can’t wrap my head around how the data from the form is been handled. Thanks

Hi, @dr3apap. I believe what @skn0tt is asking for is a new repository with a minimal reproduction of the issue occurring. If you are willing to create such a repo, please let us know.

Also, the max runtime for edge functions is 50 ms as documented here:

I don’t believe that 50 ms will be long enough for the email to be sent and for the email server to confirm the sending of the email. For this reason, I would recommend moving the code responsible for sending this email from an edge function to a normal function.

Have you tried using a function (instead of an edge function) for this?

1 Like

Hi @luke , thanks for your response. Yes I can provide a repo to reproduce the issue also I bisect the error by just returning 200 status as a response still getting 404 my inference will be it’s not about the runtime of the edge function for now, it might be in a long run as you said but right now request is not reaching the server or something different from the runtime and since this is the 404 I guess it’s the server.

When you said “normal function” do you mean normal Serverless function? I will be please to do that actually, can you combine Serverless with edge, will it have to be in same configuration file or separate config? I think this is the long run solution since the 50 ms won’t be enough whichever way.

I will be looking forward to your response while I try to integrate Sevrerless. Thanks once again.

Edge Functions should be able to send the emails, the 50 ms limit is for compute time, not for time waiting for a network request. With that being said, the normal, Lambda functions also use the same API as Edge Functions now: Get started with functions | Netlify Docs, so migration between Edge Functions and Lambda Functions should be fairly easy.