{"record":{"id":"85d74a8bbcd0e50b","repo":"nikivdev/code","slug":"invalid-sealer-secret-length","errorCode":null,"errorMessage":"invalid sealer secret length","messagePattern":"invalid sealer secret length","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sealer_crypto.rs","lineNumber":31,"sourceCode":"pub fn new_x25519_private_key() -> Vec<u8> {\n    let mut bytes = [0u8; 32];\n    SysRng\n        .try_fill_bytes(&mut bytes)\n        .expect(\"system RNG should provide x25519 key material\");\n    bytes.to_vec()\n}\n\npub fn get_sealer_id(secret: &str) -> Result<String> {\n    let secret_raw = secret\n        .strip_prefix(SECRET_PREFIX)\n        .ok_or_else(|| anyhow::anyhow!(\"invalid sealer secret prefix\"))?;\n    let private_bytes = bs58::decode(secret_raw)\n        .into_vec()\n        .map_err(|e| anyhow::anyhow!(\"invalid base58 sealer secret: {e}\"))?;\n    let bytes: [u8; 32] = private_bytes\n        .as_slice()\n        .try_into()\n        .map_err(|_| anyhow::anyhow!(\"invalid sealer secret length\"))?;\n\n    let public = PublicKey::from(&StaticSecret::from(bytes)).to_bytes();\n    Ok(format!(\n        \"{}{}\",\n        ID_PREFIX,\n        bs58::encode(public).into_string()\n    ))\n}\n\npub fn seal(\n    message: &[u8],\n    sender_secret: &str,\n    recipient_id: &str,\n    nonce_material: &[u8],\n) -> Result<Vec<u8>> {\n    let sender_secret = decode_secret(sender_secret)?;\n    let recipient_public = decode_id(recipient_id)?;\n    let sender_key = StaticSecret::from(sender_secret);","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/sealer_crypto.rs#L13-L49","documentation":"get_sealer_id requires the decoded secret bytes to be exactly 32 bytes (an x25519 scalar key). If base58 decoding succeeds but the byte length differs, this error is thrown. The secret is structurally well-formed but encodes the wrong amount of key material.","triggerScenarios":"Calling get_sealer_id with a \"sealerSecret_z\"-prefixed string whose base58 body decodes to fewer or more than 32 bytes — e.g. a truncated key or a key generated by a different scheme/curve.","commonSituations":"Truncated copy-paste, secrets generated by incompatible tooling (different key sizes), or concatenating two partial keys.","solutions":["Use the complete 32-byte secret; re-copy the full value from its source.","Regenerate the identity via create_sealer_identity / new_x25519_private_key and redistribute the new secret.","If migrating keys from another tool, re-encode exactly 32 bytes as \"sealerSecret_z\" + base58.","Verify length offline: base58-decode the body and check it is 32 bytes."],"exampleFix":"// before: truncated secret decodes to 18 bytes\nlet id = get_sealer_id(\"sealerSecret_zShortKey\")?;\n// after: full 32-byte secret\nlet id = get_sealer_id(\"sealerSecret_zFullBase58Encoded32Bytes...\")?;","handlingStrategy":"validation","validationCode":"fn sealer_secret_is_32_bytes(s: &str) -> bool {\n    s.strip_prefix(\"sealerSecret_z\")\n        .and_then(|body| bs58::decode(body).into_vec().ok())\n        .map(|v| v.len() == 32)\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match get_sealer_id(secret) {\n    Err(e) if e.to_string().contains(\"invalid sealer secret length\") => {\n        eprintln!(\"secret decodes to wrong byte length; regenerate the identity\");\n        let (new_secret, _id) = create_sealer_identity()?;\n        // persist and use new_secret\n    }\n    other => other?,\n}","preventionTips":["Always generate keys with new_x25519_private_key / create_sealer_identity.","Never hand-edit or truncate secret strings.","When migrating keys from other tools, assert 32-byte decoded length first.","Keep the full secret in one line in config/env storage."],"tags":["crypto","x25519","key-length","base58"],"backgroundTag":"invalid-key-length","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}