Fix it fast
Most likely: The manifest policy and the registry selected by the command do not agree.
Confirm this is your error
Match the output and confirm you are troubleshooting the same failure.
error: `internal-api` cannot be published. `package.publish` must be set to `true` or a non-empty list in Cargo.toml to publish.
error: The registry `company` is not listed in the `package.publish` value in Cargo.toml. Check the cause
Run focused checks to identify what is failing in this environment.
grep -n "publish" Cargo.toml
grep -nE "^default[[:space:]]*=" .cargo/config.toml "${CARGO_HOME:-$HOME/.cargo}/config.toml" 2>/dev/null
cargo publish --dry-run --registry <name> -vv Apply the safe fix
Use the smallest safe change that addresses the confirmed cause.
# Prefer selecting an already allowed registry.
cargo publish --dry-run --registry <allowed-name>
# Change package.publish only after reviewing the intended release policy. Verify it works
Repeat the relevant checks and confirm the original error is gone.
cargo publish --dry-run --registry <allowed-name> Avoid unsafe shortcuts
Keep security and data protections in place while troubleshooting.
- Do not remove
package.publishfrom internal crates merely to unblock CI. - Do not assume valid credentials grant permission to override manifest policy.
What This Error Means
Read this as a precise clue about which part of the workflow broke first. Once you know the failing layer, the fix path gets much shorter.
How to Fix It
The fastest fixes here come from checking the immediate failing layer before you change anything unrelated. Make one correction at a time and re-test from the same environment.
Intentional private package:keep the block and remove the package from release automation.
Wrong selected target:pass --registry <allowed-name> explicitly and keep the restrictive manifest policy.
Policy changed deliberately:update package.publish to the exact allowed registry list and review the accidental-publication risk.
Runner default drift:make the registry explicit in CI rather than relying on user-level registry.default
Workspace selection error:correct the release package list instead of weakening every member manifest.
Why It Happens
The crate intentionally has publish = false or publish = [] because it is private or not independently releasable.
The allowed list names a private registry, but the command is targeting crates.io or another registry.
Release automation omitted --registry and inherited an unexpected registry.default from the runner.
A copied crate template retained a restrictive policy that does not match the new package release plan.
Verify the Fix
Re-run the dry run with the same package and intended registry. Cargo should proceed from policy validation into packaging checks.
Confirm that a deliberately forbidden registry still fails, so the corrected policy has not removed more protection than intended.
Compare manifest policy with the selected registry
Inspect the [package] section of the exact manifest selected by the publish command and record the current publish value.
Inspect registry.default in the active Cargo config and any explicit --registry flag to identify the target Cargo is applying to the policy.
For workspace release automation, confirm which member was selected and whether generated manifests or inherited metadata changed its policy.
Use cargo publish --dry-run --registry <name> -vv only after the intended package and registry have been confirmed.
How package.publish enforces release policy
package.publish is a local safety policy. false or an empty list blocks every registry, while a registry-name list permits only those configured targets. Cargo checks this before packaging and upload. Valid credentials do not override the manifest policy, which helps prevent internal crates from being released publicly by mistake.
Prevent It From Coming Back
To prevent this, make --registry explicit in release jobs and keep package.publish restrictive for internal crates, review publication-policy changes as security-sensitive release configuration, and test both allowed and forbidden registry targets in reusable crate templates.
Docs and source code
Cargo Registries
Official configuration and publishing behavior for crates.io and alternative registries. - Source
Cargo installs crates and fetches dependencies from a registry. cargo publish
Official publish stages, dry-run behavior, registry selection, and authentication requirements. - Source
This command will create a distributable, compressed crate file and upload it to a registry.