Docs menu

Troubleshooting Rust

Common build and runtime errors for Rust 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 build output, including the resolved toolchain and everything cargo build prints. Toolchain errors and compiler errors surface here.
  • Runtime log: the Logs tab streams stdout and stderr from your running pods. Startup crashes, panics, and connection errors show up here.

This page lists the errors that come up most often, in the order they'd typically bite you: detection, toolchain resolution, compile, process types, then runtime.

Common build errors#

The app isn't built as a Rust app#

The build either fails with a "no language detected" error or runs another language's toolchain.

The Cargo.toml has to sit at the repo root. And because Rust is checked after every language except Bun and Node.js, another language's manifest at the root (go.mod, composer.json, requirements.txt, and so on) wins.

Fix. Move the Rust project to the repo root, or import a monorepo subdirectory as its own Primcloud app. Remove stray manifests for languages you aren't deploying.

Unsupported Rust toolchain channel#

Your rust-toolchain or rust-toolchain.toml names a channel other than stable or a released version: nightly, beta, a dated channel, or a version with a host suffix or a leading v.

Fix. Set the channel to stable, an exact version (1.99.0), or a minor version (1.99). See Runtime versions. Code that needs nightly-only features can't be built on Primcloud today.

Rust has no release for the channel#

The version in your toolchain file has the right shape but was never released.

Fix. Correct the version, or use stable.

Failed to parse the toolchain file#

rust-toolchain.toml isn't valid TOML with a [toolchain] table, or a legacy rust-toolchain file has more than one line and isn't valid TOML. A common cause is a comment or blank line added to the legacy single-line file. An empty rust-toolchain file fails the same way, with a "rust-toolchain is empty" message.

Fix. Keep the legacy file to one line holding the channel, or move to rust-toolchain.toml:

rust-toolchain.toml
[toolchain]
channel = "1.99.0"

The app has no binary target to run#

Cargo found no binary target in the package or workspace: a library-only crate, or a workspace none of whose members builds a binary. A Cargo.toml at the repo root always makes the repo a Rust app, so a native addon crate at the root of a JavaScript project ends up here too.

Fix. Add a src/main.rs or a [[bin]] target to a workspace member. If the repo isn't meant to be a Rust app, move the crate out of the repo root.

Cargo built none of the app's binary targets#

Every binary in the app declares required-features that aren't enabled. The build passes no feature flags, so Cargo skipped them all.

Fix. Add the required feature to default in [features], or drop required-features from the binary you deploy.

Couldn't run cargo metadata#

Cargo couldn't load your manifests. The underlying Cargo error is in the build log, typically a syntax error in a Cargo.toml or a workspace member path that doesn't exist.

Fix. Run cargo metadata --format-version 1 --no-deps locally and fix what it reports.

Couldn't run cargo build#

cargo build exited non-zero. The compiler or Cargo error sits directly above this line in the build log. Common causes:

  • Compile errors. Anything a normal release build can fail on.
  • Cargo.lock out of date. The build runs with --locked when a lockfile is committed. If Cargo.toml changed without it, Cargo refuses to update the lockfile and stops.
  • A dependency couldn't be downloaded. A private registry without a token, or a crate that's been removed upstream. See Package managers → Private packages and registries.
  • A native library is missing. A linker error naming a -l<library> it couldn't find, or a build.rs that fails looking for headers.

Fix. Reproduce locally with the command the build runs:

Terminal
cargo build --release --workspace --bins --locked

For a missing native library, install the -dev package through project.toml; see Customizing the build → Debian packages.

Invalid process name#

Raised when the app has several binaries and one of them has a name that isn't a valid process name.

Fix. Rename the binary to use only letters, digits, hyphens, and underscores, or ship a Procfile that names your processes explicitly.

Toolchain download failed#

The build couldn't fetch the Rust toolchain. Failed requests are retried automatically before the build gives up, so this usually means an upstream outage.

Fix. Redeploy. If your toolchain file pins a version, double-check it's a real release.

Common runtime errors#

App doesn't bind to $PORT#

Symptom: the deployment reaches Release Succeeded but the URL returns a connection error.

The build does not rewrite your launch command to inject the port. Your code has to read $PORT itself, and it has to listen on 0.0.0.0; a server bound to 127.0.0.1 isn't reachable from outside the pod.

Fix. In your web entrypoint:

let port = std::env::var("PORT").expect("$PORT must be set");
let addr = format!("0.0.0.0:{port}");

Primcloud sets PORT to 5000 on the web formation and routes traffic only there. Hard-coding a port, or leaving it at a framework default like 3000 or 8080, means requests never reach your app.

The wrong binary is serving traffic#

The app has several binaries and none is named web, so the first one Cargo lists also became the web process. The build log shows which under "Registering launch processes".

Fix. Name your web binary web, or ship a Procfile at the repo root:

Procfile
web: api
worker: worker

App exits immediately on start#

The runtime log shows the process starting and then exiting with a non-zero code.

Most common causes:

  • Panic during startup. An unwrap() or expect() on missing configuration. The panic message is in the runtime log.
  • Missing required env var. If your app reads a connection string or API key at boot, set it in the Secrets panel and redeploy.

Missing shared library at runtime#

error while loading shared libraries: libpq.so.5: cannot open shared object file

Your binary dynamically links against a shared library that isn't in the running app.

Fix. Install the missing package through project.toml; see Customizing the build → Debian packages.

Frontend files not found#

The binary starts but can't find the assets your frontend build produced.

Fix. Check the build log to confirm the frontend build ran. It needs a package.json and a committed lockfile at the repo root. The binary starts in the app root, so resolve asset paths relative to it (dist/index.html), not relative to the binary's own location. See Rust on Primcloud → Frontend assets.

Debugging tips#

  • Reproduce the build locally. cargo build --release --workspace --bins --locked is the command the build runs. Most build failures reproduce this way.
  • Check the resolved Rust version. The build log prints the channel it detected and the version it resolved. Compare it to what your toolchain file asks for. When both rust-toolchain and rust-toolchain.toml exist, rust-toolchain wins.
  • Expect one slow deploy after a toolchain bump. A new Rust version means a full recompile. The deploy after that is incremental again.