Astro app can call Mailgun api on local server, but not on CF Pages deployment?

I have an Astro project that calls the Mailgun sending api to email me the data from form submissions (env variables accessed through the "astro:env" api), and it works completely fine while running on my local dev server, but after deployment to CF Pages ("salvean.pages.dev" or just "salvean.com"), I catch an "Error: Bad Request" with form submissions calling the Mailgun api. I have also verified that my site is able to access my secret env variables on CF Pages. My DNS records for sending via Mailgun are all marked "Verified", but does this still sound like a DNS configuration issue? Thanks for your help.
1 Reply
Paeon
PaeonOP3mo ago
Here is the console.error(err) I get server-side:
"logs": [
{
"message": [
"Error: Bad Request"
],
"level": "error",
"timestamp": 1750368334451
}
],
"eventTimestamp": 1750368334106,
"event": {
"request": {
"url": "https://example.com/api/formHandler",
"method": "POST",
"headers": {
"accept": "*/*",
"accept-encoding": "gzip, br",
"accept-language": "en-US,en;q=0.9",
"cf-connecting-ip": "----:----:----:----:----:----:----:----",
"cf-connecting-o2o": "1",
"cf-ipcountry": "US",
"cf-ray": "95261987ea24a509",
"cf-visitor": "{\"scheme\":\"https\"}",
"connection": "Keep-Alive",
"content-length": "444",
"content-type": "multipart/form-data; boundary=----WebKitFormBoundaryXnFeW4PaHloonPs9",
"logs": [
{
"message": [
"Error: Bad Request"
],
"level": "error",
"timestamp": 1750368334451
}
],
"eventTimestamp": 1750368334106,
"event": {
"request": {
"url": "https://example.com/api/formHandler",
"method": "POST",
"headers": {
"accept": "*/*",
"accept-encoding": "gzip, br",
"accept-language": "en-US,en;q=0.9",
"cf-connecting-ip": "----:----:----:----:----:----:----:----",
"cf-connecting-o2o": "1",
"cf-ipcountry": "US",
"cf-ray": "95261987ea24a509",
"cf-visitor": "{\"scheme\":\"https\"}",
"connection": "Keep-Alive",
"content-length": "444",
"content-type": "multipart/form-data; boundary=----WebKitFormBoundaryXnFeW4PaHloonPs9",
Continued:
"cookie": "REDACTED",
"dnt": "1",
"host": "example.com",
"origin": "https://example.com",
"priority": "u=1, i",
"referer": "https://example.com/",
"sec-ch-ua": "\"Google Chrome\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
"x-forwarded-for": "----:----:----:----:----:----:----:----",
"x-forwarded-proto": "https",
"x-real-ip": "unix:"
},
"cf": {
"requestHeaderNames": {},
"httpProtocol": "HTTP/2",
"tlsCipher": "",
"verifiedBotCategory": "",
"continent": "--",
"asn": 7922,
"clientAcceptEncoding": "gzip, br",
"tlsClientExtensionsSha1": "",
"isEUCountry": false,
"longitude": "-----",
"tlsClientCiphersSha1": "",
"tlsClientHelloLength": "",
"tlsClientAuth": {
"certIssuerDNLegacy": "",
"certIssuerSKI": "",
"certSubjectDNRFC2253": "",
"certSubjectDNLegacy": "",
"certFingerprintSHA256": "",
"certNotBefore": "",
"certSKI": "",
"certSerial": "",
"certIssuerDN": "",
"certVerified": "NONE",
"certNotAfter": "",
"certSubjectDN": "",
"certPresented": "0",
"certRevoked": "0",
"certIssuerSerial": "",
"certIssuerDNRFC2253": "",
"certFingerprintSHA1": ""
},
"cookie": "REDACTED",
"dnt": "1",
"host": "example.com",
"origin": "https://example.com",
"priority": "u=1, i",
"referer": "https://example.com/",
"sec-ch-ua": "\"Google Chrome\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
"x-forwarded-for": "----:----:----:----:----:----:----:----",
"x-forwarded-proto": "https",
"x-real-ip": "unix:"
},
"cf": {
"requestHeaderNames": {},
"httpProtocol": "HTTP/2",
"tlsCipher": "",
"verifiedBotCategory": "",
"continent": "--",
"asn": 7922,
"clientAcceptEncoding": "gzip, br",
"tlsClientExtensionsSha1": "",
"isEUCountry": false,
"longitude": "-----",
"tlsClientCiphersSha1": "",
"tlsClientHelloLength": "",
"tlsClientAuth": {
"certIssuerDNLegacy": "",
"certIssuerSKI": "",
"certSubjectDNRFC2253": "",
"certSubjectDNLegacy": "",
"certFingerprintSHA256": "",
"certNotBefore": "",
"certSKI": "",
"certSerial": "",
"certIssuerDN": "",
"certVerified": "NONE",
"certNotAfter": "",
"certSubjectDN": "",
"certPresented": "0",
"certRevoked": "0",
"certIssuerSerial": "",
"certIssuerDNRFC2253": "",
"certFingerprintSHA1": ""
},
Continued:
"region": "-----",
"tlsVersion": "",
"colo": "-----",
"timezone": "-----",
"latitude": "-----",
"postalCode": "-----",
"edgeRequestKeepAliveStatus": 1,
"requestPriority": "",
"city": "-----",
"country": "--",
"tlsClientRandom": "",
"regionCode": "--",
"asOrganization": "Comcast Cable Communications, LLC",
"tlsClientExtensionsSha1Le": "",
"pagesHostName": "example.pages.dev",
"botManagement": {
"corporateProxy": false,
"verifiedBot": false,
"jsDetection": {
"passed": false
},
"staticResource": false,
"detectionIds": {},
"score": 99
}
}
},
"response": {
"status": 200 // Why is this status===200?
}
},
"id": 0
}
"region": "-----",
"tlsVersion": "",
"colo": "-----",
"timezone": "-----",
"latitude": "-----",
"postalCode": "-----",
"edgeRequestKeepAliveStatus": 1,
"requestPriority": "",
"city": "-----",
"country": "--",
"tlsClientRandom": "",
"regionCode": "--",
"asOrganization": "Comcast Cable Communications, LLC",
"tlsClientExtensionsSha1Le": "",
"pagesHostName": "example.pages.dev",
"botManagement": {
"corporateProxy": false,
"verifiedBot": false,
"jsDetection": {
"passed": false
},
"staticResource": false,
"detectionIds": {},
"score": 99
}
}
},
"response": {
"status": 200 // Why is this status===200?
}
},
"id": 0
}
UPDATE: I have identified the issue as the fact that Cloudflare Workers don't run in a full node environment, and thus they don't support certain dependencies in the "form-data" library. After refactoring my formHandler to make a fetch call to Mailgun's api directly rather than using the mailgun.js and form-data libraries, the issue was resolved on my deployed website.

Did you find this page helpful?