{"record":{"id":"a093182d0d986c12","repo":"stalwartlabs/stalwart","slug":"failed-to-decode-base64","errorCode":null,"errorMessage":"Failed to decode base64","messagePattern":"Failed to decode base64","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/manager/console.rs","lineNumber":247,"sourceCode":"        Some(result)\n    } else {\n        println!(\"Invalid key: {result:?}\");\n        None\n    }\n}\n\nfn parse_value(input: &str) -> Vec<u8> {\n    if let Some(key) = input.strip_prefix(\"base64:\") {\n        base64_decode(key)\n    } else {\n        parse_binary(input)\n    }\n}\n\nfn base64_decode(input: &str) -> Vec<u8> {\n    general_purpose::STANDARD\n        .decode(input)\n        .expect(\"Failed to decode base64\")\n}\n\nfn parse_binary(input: &str) -> Vec<u8> {\n    let mut result = Vec::new();\n    let mut chars = input.chars().peekable();\n\n    while let Some(c) = chars.next() {\n        if c == '\\\\' {\n            match chars.next() {\n                Some('x') => {\n                    let hex: String = chars.by_ref().take(2).collect();\n                    if hex.len() == 2 {\n                        if let Ok(byte) = u8::from_str_radix(&hex, 16) {\n                            result.push(byte);\n                        } else {\n                            result.extend_from_slice(b\"\\\\x\");\n                            result.extend_from_slice(hex.as_bytes());\n                        }","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/common/src/manager/console.rs#L229-L265","documentation":"`base64_decode` in the console module wraps `base64::general_purpose::STANDARD.decode(input)` in `.expect(\"Failed to decode base64\")`, so any invalid base64 input panics. It is used by `parse_key`/`parse_value` when console input is prefixed with `base64:`, and by PEM/blob/pkey parsing helpers (simple_pem_parse, get_blob_section, parse_public_key, verify_secret_hash). Standard-alphabet decoding with strict padding is enforced; URL-safe characters or missing/incorrect padding cause the panic.","triggerScenarios":"Typing `scan/get/put/delete` console arguments like `base64:abc!` or `base64:cmV` (invalid character, wrong length, or missing padding); passing a PEM blob, public key, or secret hash string containing URL-safe base64 (`-`/`_`), whitespace inside the payload, or truncated data into the parsing helpers.","commonSituations":"Pasting base64 from tools that produce URL-safe base64 (JWT segments, some JSON serializers) into the console; copying base64 with line breaks that were stripped incorrectly leaving stray characters; hand-truncating a key and losing `=` padding; base64 of a value copied from a doc with typographic characters.","solutions":["Validate the base64 string before use: only A-Z a-z 0-9 + / with proper = padding (or re-pad it), e.g. decode it first with `base64 -d` or a quick script.","Re-encode the data in standard (padded) base64: `echo -n \"<raw>\" | base64` and use that output after the `base64:` prefix.","Convert URL-safe base64 to standard: replace `-` with `+`, `_` with `/`, and append the required `=` padding before decoding.","Strip all whitespace/newlines from the payload before passing it, and use the `\\xNN` escaped-hex input format as a fallback when base64 keeps failing."],"exampleFix":"// before\nscan base64:cmFjYXNk base64:cmFjYXNkZg   // missing padding -> panic\n\n// after\nscan base64:cmFjYXNk base64:cmFjYXNkZg==   // correct standard padding","handlingStrategy":"validation","validationCode":"fn is_valid_standard_base64(s: &str) -> bool {\n    let trimmed: String = s.chars().filter(|c| !c.is_whitespace()).collect();\n    base64::engine::general_purpose::STANDARD.decode(&trimmed).is_ok()\n}\n// call before passing `base64:<payload>` to console commands","typeGuard":"fn safe_base64_decode(input: &str) -> Option<Vec<u8>> {\n    base64::engine::general_purpose::STANDARD.decode(input).ok()\n}","tryCatchPattern":"// replace .expect with fallible handling\nfn base64_decode(input: &str) -> Result<Vec<u8>, base64::DecodeError> {\n    base64::engine::general_purpose::STANDARD.decode(input)\n}","preventionTips":["Only paste standard, padded base64 after the `base64:` prefix — no URL-safe `-`/`_` alphabets.","Re-encode with `base64` CLI or your language's standard encoder before using console arguments.","Strip all whitespace/newlines from copied payloads.","Never truncate base64 strings manually; truncation breaks length/padding.","Prefer the `\\xNN` escaped-hex input format when base64 validation keeps failing."],"tags":["base64","decoding","console","panic","input-validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}