diff --git a/crates/svg/src/pathdata.rs b/crates/svg/src/pathdata.rs
--- a/crates/svg/src/pathdata.rs
+++ b/crates/svg/src/pathdata.rs
@@ -227,7 +227,11 @@ fn segment(l: &mut Lex, c: u8, base: Vec2, p: &mut BezPath, cur: &mut Point, las
             let e = pt(l)?;
             let arc = SvgArc { from: *cur, to: e, radii: Vec2::new(rx, ry), x_rotation: rot.to_radians(), large_arc: large, sweep };
             match kurbo::Arc::from_svg_arc(&arc) {
-                Some(a) => a.to_cubic_beziers(0.1, |c1, c2, end| p.curve_to(c1, c2, end)),
+                Some(a) => {
+                    // Scale tolerance with the radius so the segment count stays bounded.
+                    let tol = 0.1_f64.max(a.radii.x.max(a.radii.y) * 1e-4);
+                    a.to_cubic_beziers(tol, |c1, c2, end| p.curve_to(c1, c2, end))
+                }
                 None => p.line_to(e),
             }
             *cur = e;
@@ -261,6 +265,12 @@ mod tests {
     use super::*;
     use kurbo::PathEl;
 
+    #[test]
+    fn huge_arc_radius_stays_bounded() {
+        let p = parse_path_data("M0 0A1e36 1e36 0 1 1 1e30 0");
+        assert!(p.elements().len() < 1000, "got {} elements", p.elements().len());
+    }
+
     #[test]
     fn commands() {
         let p = parse_path_data("M10,10 L20,10 h10 v10 H10 z m5 5 l1-1.5.5.5e1 C 0 0 1 1 2 2 s3 3 4 4 Q1 1 2 2 t3 3 A5 5 0 0 1 20 20 a5 5 0 1010 0");
