astrid-runtime/astrid · error
WinFsp service launch exceeds limit
Error message
WinFsp service launch exceeds limit
What it means
The WinFsp private service reads its launch document (StorageProviderServiceLaunchV1) from stdin capped at SERVICE_MAX_LAUNCH_BYTES via take(SERVICE_MAX_LAUNCH_BYTES + 1). If the byte count exceeds the cap, service_main bails before JSON parsing. It is a bounded-read defense for the privileged service's IPC input.
Source
Thrown at crates/astrid-storage-provider-winfsp/src/win.rs:167
/// Request was rejected.
Failure { code: String, message: String },
}
const SERVICE_MAX_LAUNCH_BYTES: u64 = 64 * 1024;
const SERVICE_MAX_CONTROL_BYTES: usize = 64 * 1024;
const SERVICE_MAX_CALLBACK_BYTES: usize = 8 * 1024 * 1024;
const SERVICE_POLL: Duration = Duration::from_secs(1);
/// Run the hidden kernel-created `WinFsp` service mode.
pub(crate) fn service_main() -> Result<()> {
let mut bytes = Vec::new();
std::io::stdin()
.lock()
.take(SERVICE_MAX_LAUNCH_BYTES + 1)
.read_to_end(&mut bytes)
.context("read WinFsp service launch")?;
if bytes.len() as u64 > SERVICE_MAX_LAUNCH_BYTES {
bail!("WinFsp service launch exceeds limit");
}
let launch: StorageProviderServiceLaunchV1 =
serde_json::from_slice(&bytes).context("decode WinFsp service launch")?;
validate_service_launch(&launch)?;
let challenge = storage_provider_service_ready_challenge(
&launch.parent.token,
STORAGE_FILESYSTEM_SERVICE_READY_SCHEMA_V1,
crate::PROVIDER_NAME,
launch.lease.mount_id.as_uuid(),
&launch.control_path,
&launch.lease.resource_path,
&launch.lease.callback_path,
)
.map_err(anyhow::Error::msg)?;
let runtime = Arc::new(
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()View on GitHub (pinned to affd8760f4)
Solutions
- Trim the launch payload the parent writes (shorten tokens/paths, remove non-schema fields)
- Have the parent write exactly one JSON document and close stdin
- Align parent and service crate versions so the payload shape matches expectations
- Raise SERVICE_MAX_LAUNCH_BYTES in the crate only if genuinely needed, rebuilding both binaries together
Example fix
// before write_all(serde_json::to_vec(&launch_with_full_audit_log)?) // after launch.extra = None; // drop oversized optional fields write_all(serde_json::to_vec(&launch)?)
Defensive patterns
Strategy: validation
Validate before calling
let bytes = serde_json::to_vec(&launch)?;
if bytes.len() as u64 > SERVICE_MAX_LAUNCH_BYTES {
return Err(format!("launch payload {} bytes exceeds limit {}", bytes.len(), SERVICE_MAX_LAUNCH_BYTES));
} Type guard
fn launch_within_limit(launch: &StorageProviderServiceLaunchV1, max: u64) -> bool {
serde_json::to_vec(launch).map(|b| (b.len() as u64) <= max).unwrap_or(false)
} Try / catch
match service_err {
Err(e) if e.to_string().contains("launch exceeds limit") => {
eprintln!("trim launch payload or raise SERVICE_MAX_LAUNCH_BYTES");
}
other => other?,
} Prevention
- Size-check the serialized launch before writing stdin
- Avoid embedding large blobs in the launch document
- Keep parent and service binaries version-aligned
When it happens
Trigger: The parent writes a launch document larger than SERVICE_MAX_LAUNCH_BYTES to the service's stdin, e.g. oversized token fields, extra nested data, or garbage bytes beyond the JSON document.
Common situations: Embedding very long tokens or control paths in the launch; a parent/child version mismatch inflating the payload; accidental extra writes to the child's stdin pipe.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- WinFsp daemon lease exceeds limit
- WinFsp service parent process is not alive
- WinFsp service parent start identity is invalid
- WinFsp stop timed out
- provider request exceeds limit
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/53f617ac09036aa2.
Report an issue: GitHub.