astrid-runtime/astrid · error

invalid base64 filesystem payload

Error message

invalid base64 filesystem payload: {error}

What it means

decode_operation_v2 unwraps the base64-encoded data section of a Write operation using the standard base64 alphabet. If the payload is not valid base64 (bad characters, wrong padding, whitespace), the decode fails and the error is wrapped in an InvalidData io::Error with the underlying base64 message.

Solutions

  1. Encode payloads with the standard base64 engine (base64::engine::general_purpose::STANDARD) on the client side
  2. Fix padding: ensure the base64 string length is a multiple of 4 with correct '=' padding
  3. Strip whitespace/newlines from the payload before sending
  4. Log the failing base64 message from the error text to identify the exact invalid character or padding problem

Example fix

// before
let encoded = base64::engine::general_purpose::URL_SAFE.encode(&data);
// after
let encoded = base64::engine::general_purpose::STANDARD.encode(&data);
Defensive patterns

Strategy: validation

Validate before calling

use base64::engine::general_purpose::STANDARD;
fn is_valid_base64(s: &str) -> bool {
    STANDARD.decode(s.as_bytes()).is_ok()
}
assert!(is_valid_base64(&payload.data_base64), "payload must be standard-alphabet base64");

Type guard

fn validate_base64_field(op: &Operation) -> Option<&str> {
    match op {
        Operation::Write { data_base64, .. } if
            base64::engine::general_purpose::STANDARD.decode(data_base64.as_bytes()).is_ok()
            => Some(data_base64),
        _ => None,
    }
}

Try / catch

match result {
    Err(e) if e.kind() == io::ErrorKind::InvalidData
        && e.to_string().starts_with("invalid base64 filesystem payload") => {
        eprintln!("client sent malformed base64: re-encode with STANDARD engine");
    }
    other => other?,
}

Prevention

When it happens

Trigger: A Write operation sent over the mount callback socket carries a data_base64 string that the STANDARD base64 engine cannot decode — e.g. URL-safe '-_' characters, missing '=' padding, embedded newlines, or corrupted/truncated frames.

Common situations: A client base64-encodes with a URL-safe engine while the kernel expects standard; manually crafting JSON requests with unencoded binary; frames truncated mid-payload by a length-prefix bug.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/979bb47519a96a24. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-kernel/src/storage_mount.rs:640

        },
        StorageFilesystemOperationV2::Read {
            path,
            offset,
            length,
        } => StorageFilesystemOperationV1::Read {
            path,
            offset,
            length,
        },
        StorageFilesystemOperationV2::Write {
            path,
            offset,
            data_base64,
        } => {
            let data = base64::engine::general_purpose::STANDARD
                .decode(data_base64.as_bytes())
                .map_err(|error| {
                    io::Error::new(
                        io::ErrorKind::InvalidData,
                        format!("invalid base64 filesystem payload: {error}"),
                    )
                })?;
            let data_length = u64::try_from(data.len()).unwrap_or(u64::MAX);
            if data_length > STORAGE_FILESYSTEM_MAX_IO_BYTES {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    "filesystem payload exceeds limit",
                ));
            }
            StorageFilesystemOperationV1::Write { path, offset, data }
        },
        StorageFilesystemOperationV2::SetLength { path, length } => {
            StorageFilesystemOperationV1::SetLength { path, length }
        },
        StorageFilesystemOperationV2::Create { path, kind } => {
            StorageFilesystemOperationV1::Create { path, kind }

View on GitHub (pinned to affd8760f4)