Astro, fix Form error “Content-Type was not one of…”
By Flavio Copes
Fix the Astro form error 'Content-Type was not one of...' by enabling server-side rendering with output: server, or setting prerender = false on the page.
Working on a form with Astro, I got this error when submitting it:
Content-Type was not one of "multipart/form-data" or "application/x-www-form-urlencoded".
Turns out, the site was not server-side rendered, and/or the page was not hybrid.
I added output: 'server' in the Astro config in astro.config.mjs:
// @ts-check
import { defineConfig } from 'astro/config'
// https://astro.build/config
export default defineConfig({
output: 'server'
})
I could have also added
export const prerender = false
at the top of the file that included the form (and handled form submission).
Why does this error happen?
The error comes from calling Astro.request.formData() in the page frontmatter.
formData() parses the body of the incoming request. It only works when that body is actually form data, which is what the Content-Type header declares. A browser submitting a regular HTML form sends application/x-www-form-urlencoded, or multipart/form-data if the form uploads files.
On a static (prerendered) page, there is no incoming POST request at all. The frontmatter runs once at build time, against a plain GET-like request with no form body. So formData() finds a Content-Type that’s not one of the two it accepts, and throws.
That’s why the fix is switching the page to server-side rendering. With output: 'server' (or prerender = false on that one page) the frontmatter runs on every request, including the POST the form sends.
Guard the formData() call
Even on a server-rendered page, the same error can come back.
The first time someone visits the page, the browser sends a GET request. If your frontmatter calls formData() unconditionally, it runs on that GET too, and the GET has no form body.
Check the request method before parsing:
if (Astro.request.method === 'POST') {
const data = await Astro.request.formData()
const email = data.get('email')
}
Also check the form itself. If you forget method="POST" on the form tag, the browser submits with GET, puts the fields in the URL, and you hit the error again:
<form method="POST">
<input type="text" name="email" />
<button>Subscribe</button>
</form>
One last note: output: 'server' needs an adapter (Node, Netlify, Vercel…) to deploy, since the site is no longer a folder of static files. In dev mode it works right away.
Related posts about astro: