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 stdout and stderr from 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:

Terminal
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 Main in a try/catch that writes the exception to Console.Error before 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 .csproj sets <SelfContained>true</SelfContained> and targets a runtime that doesn't match the deploy image's architecture, startup fails. Publish locally with --runtime linux-x64 to reproduce.

Debugging tips#

  • Reproduce locally with the publish command. dotnet publish --runtime linux-x64 on 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=detailed on the environment, redeploy, then set it back to minimal (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.json or TargetFramework asked for.
  • Inspect the published output. Add a temporary MSBuild AfterPublish target that runs ls -R $(PublishDir) to see exactly what lands in the image: a one-line diagnostic that costs a deploy but saves guessing.