Skip to content
ContactForms

Errors

Draft. The production host names are not live yet, so the addresses on this page do not work. The table below is generated from the error catalog in the code; the docs_url links point at pages that are not all written yet.

The error body

Refusals from the public form route and the MCP endpoint are built from one catalog. A JSON refusal carries error, message, fix and docs_url and the HTTP status in the table. Three cases differ: a browser form post that fails with a visitor-fixable error is redirected (303) to a hosted error page; an MCP refusal inside a tool call is HTTP 200 with isError: true (see below); and the MCP transport itself answers protocol-level problems in its own JSON-RPC format.

{
  "success": false,
  "error": "origin_not_allowed",
  "message": "This form does not accept posts from that site.",
  "fix": "Add the site to allowed domains, or call from that site.",
  "docs_url": "https://contactforms.dev/docs/domains"
}

On POST /f/:key a JSON error also carries body.message with the same text, so a client migrated from Web3Forms finds its message where it looks. A browser post that fails with a visitor-fixable error is redirected (303) to a hosted error page instead.

MCP tool failures arrive as a tool result with isError: true and the fields error, message, fix and docs_url as JSON text. A tool that is registered but not built answers with the extra code not_available_yet, which is not in the HTTP catalog:

{
  "isError": true,
  "content": [
    { "type": "text",
      "text": "{\"error\":\"not_available_yet\",\"message\":\"list_submissions is registered but not available yet.\",\"fix\":\"...\",\"docs_url\":\"https://contactforms.dev/docs/mcp\"}" }
  ]
}

Headers

429 responses carry Retry-After. 503 responses carry it when the server knows a wait time. 405 responses carry Allow. Inside an MCP tool call the wait is in the result as retry_after_seconds, not a header. MCP 401 responses carry WWW-Authenticate: Bearer realm="contactforms".

Error codes (91)

Text in angle brackets, such as <size>, is replaced with a real value when the error is sent.

CodeStatusMessageFix
invalid_body400The request body could not be read.Send a form-encoded, multipart or JSON body.
elementor_secret_invalid401This webhook address is not valid.Copy the current Elementor webhook address from Forms > Install, including the secret at the end.
invalid_key401This key is not valid.Copy a current key from Settings > API keys.
key_revoked401This key was revoked.This key was revoked. Create a new key in Settings > API keys.
missing_credential401Sign in to continue.Send your key as `Authorization: Bearer <key>`, or sign in.
signature_invalid401The signature does not match.Check the signing secret.
webhook_signature_invalid401This webhook request is not signed correctly.Send it from the provider's webhook, signed with the endpoint's signing secret; do not edit the body.
plan_limit_forms402Your plan does not allow more forms.Archive a form you no longer use, or move to a plan that holds more forms.
plan_limit_sites402Your plan does not allow more sites.On Pro or Agency, add a site for USD 9.99 a month. On Base, upgrade to Pro.
plan_limit_storage402Your plan does not have room for the stored leads and files of this site.Delete leads you no longer need, then try again. Nothing was changed.
plan_required402Your plan does not include this.This needs the <plan> plan. See Billing for what your plan includes.
rules_limit402Your plan allows 3 routing rules.Remove a rule. Pro has unlimited rules.
account_suspended403This account is suspended.Contact support to restore the account.
claim_email_mismatch403This key was created for a different email address.Sign in with the address the key was created for (<masked>), verified, then open the claim link again.
claim_required403This key is waiting to be claimed.Open the claim link (<claim_url>) while signed in with the address it was created for. The key, the form URL and the stored leads are kept for 90 days.
client_read_only403You have view-only access.You have view-only access. Ask the agency that manages this site.
consent_required403This WordPress site has not connected with the owner's consent.In WordPress, open the ContactForms settings, tick the consent box (and the heartbeat box, for the daily health report) and connect the site. Nothing is accepted from it before that.
email_not_verified403Your email address is not verified.Verify your email address in your sign-in settings, then try again.
form_not_accepting403This form is not accepting submissions.The site owner has to renew the subscription to reopen it. Nothing you sent was stored.
key_suspended403This key is suspended.The key kept making refused or invalid requests, so it was stopped. Ask the site owner to resume it on the Agents page, and fix the loop in your agent first.
origin_not_allowed403This form does not accept posts from that site.Add the site to allowed domains, or call from that site.
role_not_allowed403Your role cannot do this.Ask a site owner to do this, or to change your role.
scope_missing403This key cannot do that.This key can only <scope>. Create a key with the scope you need.
upload_grant_invalid403These files cannot be added to that message.Send the files from the page that sent the message, right after sending it.
uploads_not_enabled403This form does not take file uploads.The form's owner adds a file field in the builder (Pro plan).
wp_mail_not_allowed403This WordPress mail is not allowed.In ContactForms open Settings > WordPress, turn mail repair on and approve the recipient. Only approved, verified recipients can be mailed, one per message.
approval_not_found404No approval was found.Check the approval link, or open the pending approvals list for this site.
destination_not_found404That destination was not found.Reload the Destinations page and pick one from the list.
form_not_found404Form not found.Check the form key (looks like f_8Kq2xLm9).
invite_invalid404This invitation cannot be used.Sign in with the email address the invitation was sent to, or ask the agency for a new invitation.
key_not_found404Key not found.Check the key ID in Settings > API keys.
route_not_found404There is no such API route.Check the path and method against the API reference.
site_not_found404Site not found.Check the site ID.
submission_not_found404Submission not found.Check the submission ID.
upload_ticket_invalid404This upload link is not valid.Ask for a new upload link; each one works once.
method_not_allowed405That method is not supported here.Use one of the methods listed in the Allow header.
approval_changed409The request changed after it was shown for approval.The request changed after approval. Ask again with the same arguments.
approval_declined409This approval was declined.The owner declined this request. Ask again only if the owner agrees.
approval_used409This approval was already used.This approval was already used. Ask again.
claim_pending409A key for this address is already waiting to be claimed.Claim it with the link we emailed, or ask for the link again: POST /api/claim/resend with that key. Or create the key with a different address.
destination_limit409This form already has the most destinations it can have.Disconnect a destination you no longer use, then add this one.
destination_paused409This destination is paused after repeated failures.Wait until the pause ends, or update the destination's settings to start again.
destination_type_unavailable409That destination type is not available yet.Use an email or webhook destination for now.
export_in_progress409An export is already being prepared.Wait for the current export to finish, then start another.
export_not_ready409This export is not ready yet.Wait until the export shows Download, then try again.
fields_in_builder409This form's fields are edited in the form builder.Open the form's Build page, change the fields there and publish.
form_archived409This form is archived.Archived forms cannot be edited. Create a new form instead.
id_conflict409That submission ID was already used with different content.Use a new _id for a different submission, or resend the original payload.
key_limit_reached409This site already has the maximum number of active keys.Revoke a key you no longer use, then create the new one.
last_owner409A site needs at least one owner.Make another member an owner first.
references_broken409Routing rules or workflows use a field you renamed or removed.Read the list, then publish again and confirm the changes, or put the field back.
stale_draft409This form was changed by someone else since you opened it.Reload the builder to see the latest version, apply your change again, and save.
stale_preview409The leads waiting for retry changed since you looked.Look at the new count and confirm again.
stale_revision409These rules were changed by someone else since you opened them.Reload the rules, apply your change again, and save.
stale_workflow409This workflow was changed by someone else since you opened it.Reload the workflow, apply your change again, and save.
upload_limit_reached409This message already has the most files it can take.A message takes at most <count> files.
upload_not_ready409The message is still being checked.Wait <seconds> and ask for the upload again.
upload_ticket_used409This upload link was already used.Ask for a new upload link; each one works once.
approval_expired410This approval expired.The approval expired. Ask again.
claim_invalid410This claim link is not valid.Ask for a new claim link: POST /api/claim/resend with your key. It is sent only to the address the key was created with.
export_expired410This export has expired.Start a new export; files are kept for 24 hours.
key_gone410This key was retired.Unclaimed keys are removed after 90 days and are never re-issued. Create a new key: POST /api/forms with your email.
upload_ticket_expired410This upload link has expired.Ask for a new upload link; each one lasts ten minutes.
file_too_large413That file is larger than allowed.Send a file of at most <size>.
payload_too_large413The request is larger than allowed.Keep the body under <size>. Send files with an upload URL.
file_type_not_allowed415That kind of file is not accepted.Send a PNG, JPEG, GIF, WebP, PDF, text, CSV, DOCX, XLSX or PPTX file whose name ends the way its contents are.
unsupported_media_type415That content type is not supported.Use application/x-www-form-urlencoded, multipart/form-data or application/json.
bad_order422That order does not list every rule exactly once.Reload the rules and move them again.
destination_config_invalid422The destination settings are not valid.Check the settings against the message shown and save again.
fallback_required422Choose who gets a lead that matches no rule.Add at least one verified recipient to the fallback, then save.
file_upload_unsupported422This endpoint takes text fields only.Send files with an upload URL; a plain form post carries text only.
invalid_email422That email address is not valid.Send a valid email address in <name>.
recipient_not_verified422That address is not a verified recipient of this form.Verify the address in the form's recipients first, then use it in a rule.
routing_invalid422The routing rules are not valid.Fix the rule named in the message and save again.
upload_failed422The upload could not be accepted.Check the file, then ask for a new upload link.
validation_failed422Some fields are not valid.Fix the fields listed in `fields`.
webhook_url_blocked422That webhook URL is not allowed.Use a public https URL (private and internal addresses are refused).
workflow_invalid422The workflow is not valid.Fix the step named in the message and save again.
approval_limit429Too many approvals are waiting.Ask the owner to approve or decline the pending requests first; an account can have 20 waiting at once.
attempt_cap429This lead has already been tried five times in the last 24 hours.Try again once the earliest attempt is more than 24 hours old.
budget_reached429A plan or safety limit was reached.A plan or safety limit was reached (<budget>). It resets <when>.
rate_limited429Too many requests.Wait <seconds> and retry.
unclaimed_cap429This unclaimed form has used its bounded allowance of held submissions.Claim the form with the link we emailed. Nothing already stored is lost. Claiming does not by itself start delivery or give a fresh allowance: that needs an active plan or trial.
export_failed500The export could not be prepared.Start the export again. If it keeps failing, see the status page.
store_failed500Nothing was saved.Nothing was saved. Retry. If it keeps failing, see the status page.
approval_unavailable503This action cannot be approved yet.This action is not available in this release. Nothing was changed.
capability_paused503This feature is paused.Retry later; the pause is lifted by the service owner or the site owner.
capacity_reached503Storage for this account is full.Delete or export leads you no longer need; new leads are accepted again as soon as space is free (<budget>).
model_not_configured503This feature is not set up yet.No model is connected yet, so nothing was run and nothing was spent. It works once the service owner connects one.
unavailable503The service is temporarily unavailable.Try again in a minute.
webhook_not_configured503This webhook endpoint is not set up on this server.Set the provider's signing secret on the server, then let the provider retry.