Docs menu
Troubleshooting .NET
Common build and runtime errors for .NET apps on Primcloud, with the fix for each.
On this page
Two places to look when a deploy misbehaves:
- Build log: the Deployments tab streams the full output from
dotnet publish. Every build error and every MSBuild error surfaces here. - Runtime log: the Logs tab streams
stdoutandstderrfrom your running pods. Startup crashes, unhandled exceptions, and native-load failures show up here.
This page lists the errors that come up most often, in the order they'd typically bite you: detection, build config, restore, publish, then runtime.
Common build errors#
No .NET application found#
The build looked for a solution file (.sln, .slnx), a project file (.csproj, .vbproj, .fsproj), or a bare .cs file at the repo root and found none.
Fix. Move the solution or project to the repo root, or open a monorepo subdirectory as its own Primcloud app.
Multiple .NET solution files#
(Same shape for multiple project files or multiple .cs files without a solution.)
The build won't guess which one to build.
Fix. Set SOLUTION_FILE as an environment variable, or set solution_file in project.toml under [com.heroku.buildpacks.dotnet], to name the one to build. See Customizing the build → Custom install steps.
Configured solution file not found#
SOLUTION_FILE or project.toml names a file that doesn't exist or isn't accessible.
Fix. Check the value against git ls-files '*.sln' locally. The path must be relative to the repo root and point at an actual file.
Missing target framework configuration#
The project file has no TargetFramework property. The build needs it to pick the SDK version to install.
Fix. Add <TargetFramework>net10.0</TargetFramework> (or the version you need) inside a <PropertyGroup> in the project file, or in a Directory.Build.props in the project directory or a parent.
Unsupported target framework#
The TFM is unrecognized, doesn't match the net{major}.0 shape, or targets a non-Linux OS (like net10.0-windows). Primcloud supports .NET 8.0 and up: net8.0 through net10.0 today.
Fix. Retarget to one of the supported TFMs; see Runtime versions.
Invalid rollForward policy in global.json#
The rollForward value isn't one the .NET SDK recognizes.
Fix. Set it to one of: patch, latestPatch, feature, latestFeature, minor, latestMinor, major, latestMajor, disable. See Microsoft's global.json reference for what each does.
Unsupported .NET SDK version#
No SDK matching the version requirement is in the Primcloud Runtime. Either the version isn't a real release, it's older than what the Runtime still ships, or rollForward: disable locked resolution to an exact patch that isn't available.
Fix. Bump to a version listed in Runtime versions, or loosen rollForward from disable to latestPatch or latestFeature so the SDK resolver can pick a close match.
dotnet publish failed#
The build invoked dotnet publish and it exited non-zero. The MSBuild error is in the build log directly above Primcloud's own error message. Missing NuGet packages, C# compile errors, and any other MSBuild-surfaced failure land there.
Fix. Read the MSBuild error and address it. To reproduce locally:
dotnet publish --runtime linux-x64
Add --verbosity normal or --verbosity detailed if the default output doesn't isolate the failing target.
Common runtime errors#
App doesn't bind to $PORT#
Symptom: the deployment reaches Release Succeeded but the URL returns a connection error, and the runtime log has no Now listening on: line.
Fix. Confirm the web process binds to the port in $PORT. For Microsoft.NET.Sdk.Web and Microsoft.NET.Sdk.Razor projects Primcloud appends --urls http://*:$PORT automatically. For other project types serving HTTP (a worker service that also exposes an HTTP endpoint, a custom entrypoint), bind to $PORT explicitly:
builder.WebHost.UseUrls($"http://*:{Environment.GetEnvironmentVariable("PORT")}");
Missing native library at runtime#
System.DllNotFoundException: Unable to load shared library 'libgdiplus'
Your code (or a native NuGet package) needs an OS-level shared library that isn't in the run image.
Fix. Declare it in project.toml; see Customizing the build → Debian packages. For libgdiplus, libmariadb, libpq, and similar, add the package name to the install list and redeploy.
App exits immediately on start#
The runtime log shows the process starting and then exiting with a non-zero code with no other output.
Most common causes:
- Startup exception before logging is configured. Wrap
Mainin a try/catch that writes the exception toConsole.Errorbefore rethrowing, redeploy, and check runtime logs for the stack trace. - Missing required env var. If your app reads a connection string or API key from an env var and throws on null, set it in the Secrets panel and redeploy.
- Framework mismatch. If your
.csprojsets<SelfContained>true</SelfContained>and targets a runtime that doesn't match the deploy image's architecture, startup fails. Publish locally with--runtime linux-x64to reproduce.
Debugging tips#
- Reproduce locally with the publish command.
dotnet publish --runtime linux-x64on your machine mirrors what the build runs, minus a couple of housekeeping args. Most build failures reproduce this way. - Turn up MSBuild verbosity temporarily. Set
MSBUILD_VERBOSITY_LEVEL=detailedon the environment, redeploy, then set it back tominimal(or unset) once you've isolated the issue. - Confirm the SDK actually installed. The build log's first section prints the resolved SDK version. Compare it to what your
global.jsonorTargetFrameworkasked for. - Inspect the published output. Add a temporary MSBuild
AfterPublishtarget that runsls -R $(PublishDir)to see exactly what lands in the image: a one-line diagnostic that costs a deploy but saves guessing.