Overview
To deploy an ASP.NET Core app in Plesk on Windows, publish it with dotnet publish, upload the contents of the publish folder (including the generated web.config) to the domain’s httpdocs folder, and make sure the server has the ASP.NET Core runtime your app targets. Plesk runs the app in IIS through the ASP.NET Core Module, so there is no separate service to start. Most failed deployments come down to a missing runtime, a wrong web.config or locked files during an update, and each has a clear fix below.
This guide is for developers deploying to Plesk for Windows hosting, whether on shared Windows hosting or their own Windows VPS. It covers uploading through File Manager and publishing straight from Visual Studio with Web Deploy, setting the environment, updating a live app without file-lock errors, and reading the startup log when the app won’t start. If you’re still choosing a platform, Linux VPS vs Windows VPS compares the two.
Prerequisites
- A domain in Plesk for Windows with hosting set up. If you’re new to the panel, see how to access Plesk on Windows Server.
- The .NET SDK on your own computer, matching your project’s target version (for example .NET 8 or .NET 10).
- Knowing which ASP.NET Core runtimes the server has. On shared hosting, ask support; on your own server, run
dotnet --list-runtimesthere. The server needs the ASP.NET Core Hosting Bundle for your version, or you publish self-contained (Step 1). - A database if your app uses one. For SQL Server, see how to configure an MSSQL database in Plesk.
Step-by-Step: Deploy an ASP.NET Core App in Plesk
Step 1: Publish the app on your computer
From the project folder, create a Release build in a publish folder:
dotnet publish -c Release -o ./publish
This is a framework-dependent build: small, and it uses the runtime installed on the server. If the server doesn’t have your exact runtime version, publish self-contained instead. The output is much larger, but it carries its own runtime:
dotnet publish -c Release -r win-x64 --self-contained true -o ./publish
Check that publish contains your app’s .dll and a web.config. The SDK generates the web.config for you; IIS needs it to hand requests to your app.
Step 2: Prepare the domain in Plesk
- Go to Websites & Domains > your domain > Hosting & DNS > Hosting.
- Untick Microsoft ASP.NET and save. That setting is for classic ASP.NET 4.x; ASP.NET Core doesn’t use it, and Plesk recommends turning it off to save server resources.
- If your plan offers a Dedicated IIS Application Pool, switch it on. ASP.NET Core apps running in-process can’t share an application pool with another ASP.NET Core app (error 500.35 below).
Step 3: Upload the published files
Option A: File Manager. Zip the contents of the publish folder (not the folder itself). In Plesk, open Files, go into httpdocs, delete the default placeholder files, upload the zip, then select it and choose Extract Files. web.config and your .dll must sit directly in httpdocs, not in a subfolder.
Option B: Web Deploy from Visual Studio. In Plesk, go to Websites & Domains > your domain > Web Deploy Publishing Settings and click Download. In Visual Studio, right-click the project, choose Publish, add a new profile, choose Import Profile and select the downloaded file. Future deployments are then one click. If the option isn’t shown in Plesk, Web Deploy isn’t installed on that server; ask support or use Option A.
Option C: FTP. Upload the contents of publish into httpdocs with any FTP client, using the FTP account from Plesk.
Step 4: Set the environment and connection string
An app deployed to a server runs as Production by default, so it reads appsettings.json and appsettings.Production.json. Put the production connection string in appsettings.Production.json, or set values as environment variables in web.config:
<aspNetCore processPath="dotnet" arguments=".\MyApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
Keep the processPath and arguments the SDK generated; only add the environmentVariables block. A self-contained build has processPath=".\MyApp.exe" and no arguments.
Note: dotnet publish overwrites web.config on every build. If you edit it on the server, copy the change back into the project (add a web.config to the project root) or it will be lost at the next deployment. For redirect and rewrite rules in that file, see web.config redirects and URL Rewrite in Plesk.
Step 5: Update a live app without file-lock errors
While the app is running, IIS keeps its .dll files locked, so overwriting them fails part-way through an upload. Take the app offline for the few seconds the upload takes:
- Upload a file named exactly
app_offline.htmtohttpdocs. It can contain a short “back in a minute” message. The ASP.NET Core Module shuts the app down and shows that page to visitors. - Upload the new build.
- Delete
app_offline.htm. The next request starts the new version.
If you publish with Web Deploy, it can do this for you: add <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline> inside the PropertyGroup of your publish profile (the .pubxml file under Properties/PublishProfiles).
Verify the deployment
Open the site in a browser. If you see your app, check a page that reads from the database too, since a bad connection string usually only shows up there. Then secure the site with an SSL certificate from SSL/TLS Certificates on the domain and add HTTPS redirection if your app doesn’t already use app.UseHttpsRedirection(). If you see an HTTP 500 error instead, the section below matches the error number to the fix.
Common Issues & Troubleshooting
For any 500.3x error, turn on the startup log first. It records the exception that stopped the app:
- Create a folder named
logsinhttpdocs. The module won’t create it for you. - In
web.config, setstdoutLogEnabled="true"(thestdoutLogFile=".\logs\stdout"value from Step 4 is correct). - Load the site once, then open the newest
stdout_*.logfile inlogswith Plesk’s File Manager. - Set it back to
falsewhen you’re done.
Warning: The stdout log has no size limit and creates a new file on every start. Left on, it can fill your disk quota.
HTTP Error 500.30 – ASP.NET Core app failed to start
Cause: The runtime loaded, but your app threw an exception during startup. The usual reasons are a wrong connection string, a missing appsettings value, or a file or folder the app can’t write to.
Fix: Turn on the stdout log as above and read the exception. For database errors, check the server name, database and credentials against Plesk’s Databases page. For permission errors, give the site write access to the folder in Files > Change Permissions.
HTTP Error 500.31 – Failed to load ASP.NET Core runtime
Cause: The server doesn’t have the ASP.NET Core runtime version your app targets, for example an app built for .NET 10 on a server with only .NET 8.
Fix: Retarget the app to a version the server has, publish it self-contained (Step 1), or ask for the matching Hosting Bundle to be installed. On your own server, install the Hosting Bundle and restart IIS with iisreset; how to install and configure IIS covers the IIS side.
HTTP Error 500.19 – Internal Server Error
Cause: IIS can’t read web.config. Either the file has an XML error, or the ASP.NET Core Module isn’t installed, so IIS doesn’t recognise the aspNetCore section.
Fix: Compare your web.config with the one dotnet publish generated and undo manual edits. If the file is untouched, the server is missing the Hosting Bundle; ask support to install the ASP.NET Core component.
HTTP Error 500.35 – ASP.NET Core does not support multiple apps in the same app pool
Cause: Two in-process ASP.NET Core apps share one IIS application pool, typically a second app in a subfolder or on a subdomain under the same subscription.
Fix: Turn on the dedicated application pool (Step 2) and run each app on its own domain or subdomain with its own pool. If that isn’t possible, switch the second app to out-of-process hosting by setting hostingModel="outofprocess" in its web.config.
The process cannot access the file because it is being used by another process
Cause: You uploaded over a running app and IIS still holds its files open.
Fix: Upload app_offline.htm first, as in Step 5, then retry the upload and remove the file afterwards.
Frequently Asked Questions
Does Plesk for Windows support ASP.NET Core?
Yes, when the server has the Microsoft ASP.NET Core component and the matching .NET Hosting Bundle installed. The app runs in IIS through the ASP.NET Core Module. Ask your host which .NET versions are available, or publish your app self-contained so it brings its own runtime.
Where do I upload my ASP.NET Core files in Plesk?
Upload the contents of your publish folder into the domain’s httpdocs folder, so web.config and your app’s .dll sit directly inside httpdocs. Uploading the publish folder itself as a subfolder is the most common reason the site shows a directory listing or a 403 error.
Should I publish framework-dependent or self-contained?
Use framework-dependent when the server has your exact runtime version, because the upload is small and security updates to the runtime apply automatically. Use self-contained when the server lacks your version, since it includes the runtime, at the cost of a much larger upload that you update yourself.
How do I see why my ASP.NET Core app won’t start?
Create a logs folder in httpdocs, set stdoutLogEnabled to true in web.config, load the site once and read the newest stdout log file in Plesk’s File Manager. It shows the exception that stopped the app. Turn logging off afterwards because the files are never cleaned up automatically.
Can I publish directly from Visual Studio to Plesk?
Yes, if Web Deploy is installed on the server. Download the publishing settings from Websites & Domains > your domain > Web Deploy Publishing Settings in Plesk, then import that file as a publish profile in Visual Studio. Each later deployment is a single click.