---
title: "Form is not submitting"
description: "What to check when submitting doesn't produce an accepted response — validation, identity, network, and server errors."
group: "Reference"
order: 0
type: "troubleshooting"
parent: "troubleshooting"
keywords:
  - "submit error"
  - "validation"
  - "network"
  - "response rejected"
updated: "2026-07-14"
---

Start with the browser network panel. A form that stays on the page might be waiting on validation, blocked before any request fires, or showing a server rejection. The status code and JSON body usually tell you which.

## Check the visible form state

1. Complete every required visible field.
2. Move through every page. A required answer on an earlier page can still block submission.
3. Confirm numeric, email, URL, phone, date, and file values satisfy their field rules.
4. Look for an inline error near the first invalid field and the summary around the submit action.

Conditional logic matters here. A hidden field isn't required while it's hidden, but an answer can reveal another required field or route the respondent to a different page.

## Inspect the submission request

Open the browser developer tools, choose **Network**, and submit again. Find the request to the Fillo responses endpoint.

| Result | What it usually means | Next check |
| --- | --- | --- |
| No request | Client validation or application code stopped submission | Inspect field errors and custom submit handlers |
| `400` | The answer payload doesn't match the published schema | Read the structured field errors and compare field IDs |
| `401` or `403` | Required person identity is missing or the private credential is invalid | Verify the identity context or credential type |
| `404` | The form ID, slug, or published version can't be resolved | Publish the form and check the embed target |
| `422` | A required response-limit scope can't be resolved | Check the configured scope field and submitted value |
| `413` | The request exceeded a body or file limit | Upload files through the file flow, not inside JSON |
| `429` | A form, workspace, or network rate limit fired | Stop automatic retries and try after the indicated delay |
| `5xx` | Fillo or a storage provider failed | Preserve the response body and request ID before retrying |

Reading and submitting a published form doesn't need a publishable key — and don't add a private workspace key to browser code as a workaround. One caveat: a keep-first repeat can intentionally return an ordinary accepted response shape, so it doesn't leak whether another person's answer exists. Diagnose repeats from the renderer's duplicate state or the visible already-answered message, not by inferring duplicates from a single HTTP status.

## Custom renderer checks

If you built a custom UI, use the controller's `setValue`, navigation, and `submit` methods rather than assembling your own payload. Keep the controller alive until submission finishes, surface its errors, and make sure your HTML form doesn't fire a second native page submission.

```ts
const result = await controller.submit();

if (!result.ok) {
  console.error(result.error);
}
```

If your app intercepts `onSubmit`, await the promise and display both field-level and form-level errors. A disabled button with no progress state can make a pending request look broken.

## Isolate the failing layer

Try the published hosted form directly. If it works there but not in your embed, compare the form ID, API origin, respondent context, URL parameters, and custom event code. If both fail, inspect the published schema and dashboard settings.

## Related

- [Blocked by CORS policy](/docs/troubleshooting/cors-error): Diagnose requests stopped by the browser.
- [Response limits](/docs/response-limits): Understand repeat-submission rejections.
- [Form failed to publish](/docs/troubleshooting/publish-failed): Repair a schema that never became live.
