astrid-runtime/astrid · error
legacy capsule migration exceeds the bounded principal limit
Error message
legacy capsule migration exceeds the bounded principal limit ({MAX_PRINCIPALS_PER_PASS}) What it means
Legacy capsule migration processes principals in bounded passes and hard-caps a single pass at MAX_PRINCIPALS_PER_PASS = 4096 bindings. If the principal directory contains more than 4096 aliases, the migration refuses to run rather than perform an unbounded loop that could take unbounded time or memory. This is a deliberate safety bound, not a corruption indicator.
Source
Thrown at crates/astrid-capsule-install/src/storage/migration.rs:265
.entry(receipt.uid)
.or_default()
.push(receipt.capsule_id);
}
Ok(migrated.into_iter().collect())
}
/// Import legacy capsule directories for every admitted principal and return
/// a canonical authority-retirement proof for the barrier ledger.
pub fn migrate_all_native_capsules_with_report(
store: &Arc<RuntimePrincipalStore>,
home: &astrid_core::dirs::AstridHome,
directory: &astrid_storage::PrincipalDirectory,
workspace_targets: &[std::path::PathBuf],
) -> anyhow::Result<LegacyCapsuleMigrationReport> {
const MAX_PRINCIPALS_PER_PASS: usize = 4096;
let bindings = directory.bindings();
if bindings.len() > MAX_PRINCIPALS_PER_PASS {
bail!(
"legacy capsule migration exceeds the bounded principal limit ({MAX_PRINCIPALS_PER_PASS})"
);
}
let mut report = LegacyCapsuleMigrationReport::default();
for (alias, _uid) in bindings {
let principal_report =
migrate_native_capsules_with_report(store, home, &alias, workspace_targets)?;
report
.retired_authorities
.extend(principal_report.retired_authorities);
}
report.retired_authorities.sort();
Ok(report)
}
/// Receipt status for one admitted principal's legacy env/secret boundary.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct LegacyEnvSecretImportStatus {View on GitHub (pinned to affd8760f4)
Solutions
- Reduce the number of principals in the directory before migrating (archive or delete unused aliases).
- Split the principal directory into batches and migrate each batch against a directory view containing at most 4096 bindings.
- Raise MAX_PRINCIPALS_PER_PASS in a patched build if your workload genuinely needs larger passes (accepting longer migration runs).
- Contact maintainers if you need chunked migration support upstream.
Example fix
// before migrate_all_native_capsules(&home, &directory)?; // bails with >4096 bindings // after: prune unused bindings first let bindings: Vec<_> = directory.bindings().into_iter().collect(); assert!(bindings.len() <= 4096, "prune principals before migrating"); migrate_all_native_capsules(&home, &directory)?;
Defensive patterns
Strategy: validation
Validate before calling
let count = directory.bindings().len();
if count > 4096 {
return Err(anyhow::anyhow!(
"{} principals exceed the 4096 per-pass migration limit; prune or batch first", count));
} Type guard
fn within_pass_limit(bindings: &[(String, u64)]) -> bool {
bindings.len() <= 4096
} Try / catch
match migrate_all_native_capsules(&home, &directory) {
Ok(report) => { /* ... */ }
Err(e) if e.to_string().contains("bounded principal limit") => {
eprintln!("too many principals: batch the migration");
}
Err(e) => return Err(e),
} Prevention
- Monitor principal-directory size; alert before it approaches 4096 bindings.
- Prune stale/unused aliases as routine maintenance.
- Design bulk principal creation with batching in mind.
- Pin the astrid version you rely on if you patch MAX_PRINCIPALS_PER_PASS locally.
When it happens
Trigger: Calling migrate_all_native_capsules or migrate_legacy_layout when directory.bindings() returns more than 4096 entries.
Common situations: Very large or long-lived legacy installs with thousands of principal aliases; directories accumulated junk aliases over years; a test or script created thousands of principals.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- legacy env/secret status exceeds the bounded principal limit
- legacy capsule component path is not relative
- legacy capsule metadata has no WASM hash
- legacy capsule WIT path is not relative: {}
- legacy capsule directory {id} does not match manifest id {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/71f7fe41a868c007.
Report an issue: GitHub.