{"record":{"id":"a768adbcb8c351c0","repo":"remotion-dev/remotion","slug":"invalid-side-data","errorCode":null,"errorMessage":"Invalid side data","messagePattern":"Invalid side data","errorType":"exception","errorClass":"ErrorWithBacktrace","httpStatus":null,"severity":"warning","filePath":"packages/compositor/rust/rotation.rs","lineNumber":14,"sourceCode":"use std::{f64::consts::PI, io::ErrorKind};\n\nuse crate::errors::ErrorWithBacktrace;\n\npub fn get_from_side_data(value: &[u8]) -> Result<f64, ErrorWithBacktrace> {\n    let mut i32_values: Vec<i32> = Vec::new();\n\n    for bytes in value.chunks(4) {\n        let i32_value = i32::from_le_bytes(bytes.try_into().unwrap());\n        i32_values.push(i32_value);\n    }\n\n    if i32_values.len() != 9 {\n        Err(std::io::Error::new(ErrorKind::Other, \"Invalid side data\"))?;\n    }\n    return get_rotation(&i32_values);\n}\n\npub fn get_rotation(displaymatrix: &[i32]) -> Result<f64, ErrorWithBacktrace> {\n    let mut theta = -(rotation_get(displaymatrix))?.round();\n\n    theta -= 360.0 * (theta / 360.0 + 0.9 / 360.0).floor();\n\n    if (theta - 90.0 * (theta / 90.0).round()).abs() > 2.0 {\n        Err(std::io::Error::new(ErrorKind::Other, \"Odd rotation angle\"))?;\n    }\n\n    return Ok(theta);\n}\n\npub fn rotation_get(matrix: &[i32]) -> Result<f64, ErrorWithBacktrace> {\n    let scale0 = (matrix[0] as f64).hypot(matrix[3] as f64);","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/compositor/rust/rotation.rs#L1-L32","documentation":"Thrown by get_from_side_data when the display-matrix side data does not parse into exactly 9 little-endian i32 values. The display matrix is a 3x3 affine transform, so any other length indicates corrupt or non-rotation side data.","triggerScenarios":"Reading AVPacket/AVFrame side data whose length is not a multiple of 4, or whose i32 count is not 9; passing arbitrary side-data blobs (e.g. non-display-matrix metadata) into get_from_side_data.","commonSituations":"Containers that attach unrelated side data that the rotation reader does not recognize; partially-written media where side-data is truncated; an ffmpeg version that changes the side-data payload format.","solutions":["Validate side_data.len() >= 36 and is a multiple of 4 before calling, and skip rotation parsing otherwise (treat as 0 degrees).","Re-mux the source so the display matrix is written correctly, or strip rotation metadata with `-metadata:s:v:0 rotate=` if it is spurious.","Only pass display-matrix side data (AV_FRAME_DATA_DISPLAYMATRIX / AV_PKT_DATA_DISPLAYMATRIX) to this function."],"exampleFix":"// before\nlet rot = get_from_side_data(&side_data)?;\n\n// after\nif side_data.len() < 36 || side_data.len() % 4 != 0 {\n    return Ok(0.0); // no usable rotation metadata\n}\nlet rot = get_from_side_data(&side_data).unwrap_or(0.0);","handlingStrategy":"validation","validationCode":"fn valid_display_matrix(data: &[u8]) -> bool {\n    data.len() >= 36 && data.len() % 4 == 0 && data.len() / 4 == 9\n}\nif !valid_display_matrix(&side_data) { return Ok(0.0); }","typeGuard":"null","tryCatchPattern":"let rot = match get_from_side_data(&side_data) {\n    Ok(r) => r,\n    Err(_) => 0.0, // tolerate non-matrix side data\n};","preventionTips":["Only pass display-matrix side data to the rotation reader.","Treat unreadable rotation metadata as 0 degrees upstream.","Strip spurious side data on remux if not needed."],"tags":["rust","ffmpeg","rotation","side-data","displaymatrix"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}