> Markdown version of [Troubleshooting](https://vaadin.com/docs/next/flow/production/troubleshooting). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Troubleshooting Production Mode

This page provides some suggestions in case you have problems taking Vaadin applications to production.

## <a id="verifying-production-mode-artifact"></a>Verifying Production Mode Artifact

Vaadin Servlet configures itself from the `flow-build-info.json` file, which is located in the `META-INF/VAADIN/config/` resource package.

The location of resources differs, though, for different artifact types. For example, the Spring Boot `JAR` file places resources into the `BOOT-INF/classes/` folder in the `JAR` file. Whereas, the `WAR` archive puts them in the `WEB-INF/classes/` folder.

If production mode has been activated, the contents of the `flow-build-info.json` should be as follows:

flow-build-info.json

```json
{
  "productionMode": true,      (1)
  "frontendHotdeploy": false
}
```

1. The `productionMode` property is set to `true`.

It’s very important that this file be precise once on the classpath in production mode. If the file is missing, Vaadin Servlet uses other means to examine whether it’s running in production mode, such as the value of the `vaadin.productionMode` system property.

Depending on the outcome, Vaadin may throw an exception at runtime like this:

```
Failed to determine project directory for dev mode...
```

Or it may return a message like this:

```
The compatibility mode is explicitly set to 'false', but there are neither 'flow-build-info.json' nor 'vite.config.ts' files
```

Vaadin may also decide to start in development mode. The Vaadin configuration is then governed by a different set of rules: for example, the `project.basedir` property or similar.

### <a id="flow-build-info-json-file"></a>`flow-build-info.json` File

The project `flow-build-info.json` file is generated by the Vaadin plugin in the `build-frontend` Maven goal.

If the file is present multiple times on the classpath, then Vaadin tries to choose the right one coming from the main project. If it isn’t possible to do this, Vaadin prints a warning message and chooses the first `flow-build-info.json` file. This depends on the ordering in the classpath, which in turn may depend on the ordering of files in the file system or in the `WAR`/`JAR` archive.

This confusion can happen when a Vaadin add-on incorrectly includes the `flow-build-info.json` file in the `JAR` file. This is a bug in the add-on packaging, which needs to be fixed. Also, the `flow-build-info.json` file needs to be removed from the add-on’s `JAR` file.

For the reasons stated, make sure the `flow-build-info.json` file is on the classpath only once, and is always coming from your main project.

### <a id="stats-json-file"></a>`stats.json` File

A file named `META-INF/VAADIN/config/stats.json` is generated by the Maven plugin, as well. It’s important to check for the presence of this file in the resources folder.

When packaging for production, a Vite executable is run. This happens in the `build-frontend` Maven goal. Vite is then responsible for packaging everything from `frontend/` and `node_modules` into the pre-compiled JavaScript files bundle. The bundle is located in the `META-INF/VAADIN/build/` resource folder. The folder contents should look like this:

```
├── FlowBootstrap.0b77bed3.js
├── FlowBootstrap.0b77bed3.js.br
├── FlowClient.947c8d40.js
├── FlowClient.947c8d40.js.br
├── generated-flow-imports-fallback.348e3eaf.js
├── generated-flow-imports-fallback.348e3eaf.js.br
├── generated-flow-imports.b6dfc59f.js
├── generated-flow-imports.b6dfc59f.js.br
├── indexhtml.e5efd5b3.js
├── indexhtml.e5efd5b3.js.br
├── webcomponenthtml-5467a14d.js
└── webcomponenthtml-5467a14d.js.br
```

Note, the hashes differ with each build.

## <a id="maximum-request-body-size"></a>Maximum Request Body Size

Flow limits the size of client-to-server UIDL/RPC and push request bodies. By default, a request whose body exceeds 10 MB is rejected with an HTTP `413` (Request Entity Too Large) response. Normal application interactions stay well below this limit, so reaching it is uncommon — but a view that sends a very large amount of data to the server in a single request can exceed it.

To allow larger requests, increase the limit — or set it to `-1` to disable it — with the `maxRequestBodySize` configuration property. The limit doesn’t apply to file uploads, which are streamed in chunks and have their own separate size limits. See [Configuration Properties](https://vaadin.com/docs/next/flow/configuration/properties.md) for how to set the property.

## <a id="common-issues"></a>Common Issues

Below are some common issues faced when attempting to go to production with an application, along with suggestions for resolving them.

- The application won’t start after building for production.

  One potential cause of this problem is that the `build-frontend` goal of the `vaadin-maven-plugin` wasn’t executed, either because the plugin is missing from the `pom.xml` file, or it’s missing in the configuration. To resolve this, add the `vaadin-maven-plugin` to your Maven `build` block and enable the `build-frontend` goal.

- Frontend resources are missing or not loaded in the running application.

  A production build can result in a running application without properly loaded frontend resources due to a misconfigured `vaadin-maven-plugin`.

  To ensure that the production build packages all resources correctly, make sure the `vaadin-maven-plugin` is executed after the `maven-compiler-plugin`. This can be achieved either configuring the execution goal of `vaadin-maven-plugin` to run after the goal targeted by `maven-compiler-plugin`, or if both target the same goal, placing the `vaadin-maven-plugin` definition after the `maven-compiler-plugin` in your `pom.xml`. The same applies for `kotlin-maven-plugin` or any other plugin that produces Vaadin related Java classes.

- When running multiple Vaadin applications on different ports on the same host, the browser tabs keeps reloading the page.

  The cause of page reloading is possibly due to server session expiration caused by all Vaadin application having the same HTTP session cookie name (e.g., `JSESSIONID`). Cookies for a given host are shared across all of the ports on that host, even though "same-origin policy", typically used by web browsers, isolates content retrieved via different ports.

  This mean the value from one application is overridden by another. To resolve this, configure a different HTTP session cookie name for each application instance. In a Spring Boot application, the cookie name can be set with the [server.servlet.session.cookie.name](https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties.server.server.servlet.session.cookie.name) property. Another possibility is to get the `SessionCookieConfig` instance from the `ServletContext` and use the `setName(String)` method to change cookie name.

  See [HTTP State Management Mechanism RFC](https://datatracker.ietf.org/doc/html/rfc6265#section-8.5) for more information.

- The application runs out of memory, and the heap holds a large number of pending JavaScript invocations.

  JavaScript scheduled from the server with `executeJs()` is kept in memory until it’s written into a response for the browser, so an application that keeps scheduling invocations which are never delivered grows until it fails. Flow logs a warning once 1000 invocations for one UI are waiting to be sent, naming the component they belong to and why nothing is being delivered.

  See [Undelivered Invocations](https://vaadin.com/docs/next/flow/component-internals/element-api/calling-javascript.md#undelivered-invocations) for the causes and for what to do instead.

`9A4AD367-94A0-4933-AE09-1A08016E6E58`
