Continuing the ELI5 series, this time it’s all about deploying apps to production environments. Your app is done, how do you deploy to production, check it out:

In this video, Erik walks through the complete process of deploying a Business Central app to a production environment. He covers the step-by-step upload process, common errors you’ll encounter, how to handle version numbering, the “deploy to” options for scheduling deployments around upgrades, and how to use the force sync option when you have breaking schema changes.
You Can’t Deploy to Production from Visual Studio Code
The first thing to understand is that you cannot deploy directly to a cloud production environment from Visual Studio Code. When you look at your launch configurations, you’ll see options to publish to a cloud sandbox or to your own server — but a cloud production environment is neither of those options.
Instead, what you need to do is work with the output .app file that Visual Studio Code generates when you build your project. This is the artifact you’ll upload manually through the Business Central web client.
As a side note, Erik mentions that he uses the AL Object Designer extension by Andreas, which allows you to click on an .app file and see its contents directly — a fantastic tool for AL developers.
Uploading Your App Through Extension Management
To deploy your app, navigate to your production environment in the Business Central web client and search for Extension Management. Here you’ll see all the apps currently installed in your environment.
You’ll notice a column called “Published As” which tells you how each app got into your system:
- Global — Apps pre-deployed from Microsoft (like the Base Application) or installed from AppSource
- Dev — Apps deployed from Visual Studio Code (only seen in sandbox environments)
- PTE (Per Tenant Extension) — Apps that are not from Microsoft or AppSource, uploaded directly to this tenant
Erik notes that it would be nice if the interface distinguished between Microsoft-published global apps and those installed from AppSource, but currently it doesn’t.
Timing Considerations
Before uploading, consider doing your deployment during off-hours. The upload process may lock certain tables and prevent users from working, so plan accordingly.
The Upload Process
From Extension Management, click Upload Extension, select your .app file, and you’ll see several options:
The Force Option
Introduced in version 19, the Force checkbox allows you to push through breaking schema changes. For a first-time upload, it has no effect. But if you’re uploading an update that includes breaking changes — like reducing a field length, changing primary keys, or deleting fields — you’ll need to check this option.
Be careful with Force: It can result in data loss. Some data simply cannot survive a brute-force schema change. If you’re changing primary keys, you might lose records. This should be your last resort — the “we deployed something wrong and need to fix it” option.
The “Deploy To” Option
You have three choices for when the deployment takes effect:
- Current version — Deploys immediately to the current version of Business Central
- Next minor — The app sits and waits until the next minor update (e.g., 19.1 to 19.2)
- Next major — The app waits until the next major update (e.g., 19.x to 20.x)
The scenario for using “Next minor” or “Next major” is when you’ve tested on a sandbox that’s already been upgraded and discovered that your current code won’t work on the next version. You upload the fix, and Microsoft stores it and applies it at upgrade time.
The big gotcha: There is no cancel function. Once you upload an app targeting the next minor or major, that’s the plan you’re going with. Erik shares a real-world experience where he uploaded an app waiting for the next major, but then had an urgent need to upload something to the current version — and couldn’t, because there was already an app queued up. His workaround in such cases has been to uninstall the app (without deleting data) and then re-upload the new app after the upgrade completes.
Erik’s recommendation: only use the “Next minor/major” options if you know the upgrade is happening imminently, like tonight.
Checking Deployment Status
After clicking Deploy, you’ll see a message: “Extension deployment is in progress. Please check the deployment status page for update.”
Navigate to Manage → Deployment Status to monitor progress. This screen has some quirks:
- It doesn’t auto-refresh — press F5 (just plain F5, not Ctrl+F5) to refresh the content
- Deployment times vary — sometimes it’s nearly instant, other times it takes minutes, possibly because deployments go into a queue on Microsoft’s side
- If you upload the same version number again, it overrides the deployment line for that version, which can make a previously “Completed” status appear as “Failed”
Common Errors and How to Fix Them
Missing Permission Set (PTE-004)
Erik deliberately demonstrates this error. When uploading to production, your app must include a permission set that covers the app’s objects. The error message reads:
Package validation failed: PTE-004 - Table 757100 is missing a matching permission set.
The fix is straightforward: add the required permission set to your app, rebuild, and upload again. There’s a separate video on the channel covering permission sets as objects in AL.
Duplicate Version Number
If you try to upload the same version number that’s already been deployed (even if the previous deployment of that version failed at some point in the process), you’ll get:
Deployment operation rejected: A different app file with the same App ID and version
has already been uploaded to our service. Please verify that the App ID associated
to this extension is the correct one. Increment the version number to one that has
not been used, or redeploy the package.
The solution: go into your app.json file and increment the version number:
{
"version": "1.0.0.1" // Incremented from "1.0.0.0"
}
Rebuild, and upload the new .app file.
Breaking Schema Changes
If your update includes a breaking change — like reducing a field’s data length — the deployment will fail with an error like:
Could not upgrade the extension "Point of Sale" due to the following error:
Table POS Setup - the field "Cash Customer" has reduced the length of the
data type from 20 to 18. Reducing the length of data type on fields is not allowed.
To push through this change, re-upload the same .app file but this time check the Force checkbox. Remember, this can cause data loss, so use it carefully.
A Note on Terminology
Erik points out that some of the terminology in Business Central’s extension management — “publish,” “unpublish,” “install,” “per tenant” — is inherited from the NAV multi-tenant era (around NAV 2016). In that world, partners would run multiple customers as separate tenants on the same server, so you would “publish” an app to the server and then “install” it on individual tenants.
In today’s SaaS world, as a developer or partner, you can only see and operate on a single tenant. The distinction between publishing and installing is largely irrelevant from your perspective, even though Microsoft still manages thousands of tenants behind the scenes. The terminology can be confusing, but understanding its origin helps make sense of it.
Automation Options
While this video demonstrates the manual process, there are many ways to automate deployment:
- Build servers that produce
.appfiles on check-in to source control - Scheduled builds that store artifacts in a central location
- Deployment tools like AL-Ops that can schedule and execute deployments automatically
Whether automation is worth the setup depends on your deployment frequency. If you’re deploying once a month or every two weeks, Erik personally doesn’t see the need for automation since the manual process only takes a couple of minutes. But your mileage may vary.
Summary
Deploying a Business Central app to production is a straightforward process, but there are several important things to keep in mind:
- You cannot deploy to a cloud production environment from Visual Studio Code — you must upload the
.appfile through the web client’s Extension Management page - Always ensure your app includes a permission set covering its objects
- Increment your version number in
app.jsonfor each upload - Consider deploying during off-hours to avoid locking users out of tables
- Use the “Deploy to Next Minor/Major” options sparingly, and only when the upgrade is imminent — there’s no cancel button
- Use the Force option as a last resort for breaking schema changes, and be aware it can cause data loss
- Monitor the Deployment Status page and refresh with F5 to see updates