AvaloniaUI/Avalonia · error · InvalidOperationException
Invalid render scaling value {scaling}
Error message
Invalid render scaling value {scaling} What it means
ValidateScaling throws when the render/DPI scaling factor is zero, negative, or non-finite (NaN/Infinity). LayoutHelper.ValidateScaling guards every layout hot path so that a bogus scaling value never propagates into pixel-snapping math (RoundTo8Digits) which would produce corrupt layout geometry. A valid scaling value must be a strictly-positive finite double.
Source
Thrown at src/Avalonia.Base/Layout/LayoutHelper.cs:267
return dpiScale == 1.0 ?
Math.Ceiling(value) :
Math.Ceiling(RoundTo8Digits(value) * dpiScale) / dpiScale;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double RoundTo8Digits(double value)
{
// Round the value to avoid FP errors. This is needed because if `value` has a floating
// point precision error (e.g. 79.333333333333343) then when it's multiplied by
// `dpiScale` and rounded up, it will be rounded up to a value one greater than it
// should be.
return Math.Round(value, 8, MidpointRounding.ToZero);
}
internal static double ValidateScaling(double scaling)
{
if (MathUtilities.IsNegativeOrNonFinite(scaling) || MathUtilities.IsZero(scaling))
throw new InvalidOperationException($"Invalid render scaling value {scaling}");
if (MathUtilities.IsOne(scaling))
{
// Ensure we've got exactly 1.0 and not an approximation,
// so we don't have to use MathUtilities.IsOne in various layout hot paths.
return 1.0;
}
return scaling;
}
}
}
View on GitHub (pinned to 11c5427268)
Solutions
- Check the platform DPI scale provider implementation — it must return a strictly positive finite value.
- In tests/headless scenarios, ensure the test host (e.g. Avalonia.Headless) is configured and provides a valid scale.
- Guard the scaling value before it reaches layout: if non-positive or non-finite, substitute a safe default like 1.0.
- Inspect the call stack to find which platform/render layer supplied the degenerate value and fix it at the source.
Example fix
// before double scale = GetScaleFromPlatform(); // returns 0 or NaN in headless // after double scale = GetScaleFromPlatform(); if (double.IsNaN(scale) || scale <= 0) scale = 1.0;
Defensive patterns
Strategy: validation
Validate before calling
static double SafeScale(double scale) =>
double.IsNaN(scale) || double.IsInfinity(scale) || scale <= 0 ? 1.0 : scale;
// usage before any layout/render code expecting a scale
var safe = SafeScale(reportedScale); Try / catch
try
{
LayoutHelper.ValidateScaling(scaling);
}
catch (InvalidOperationException)
{
scaling = 1.0; // fall back to identity scale
LayoutHelper.ValidateScaling(scaling);
} Prevention
- In headless/test environments, configure the test host to provide a valid scale.
- Never pass uninitialized or computed-without-guard scaling values to layout APIs.
- Wrap platform DPI providers so they clamp degenerate values to 1.0.
When it happens
Trigger: An internal or platform call to LayoutHelper.ValidateScaling(scaling) where scaling is 0, negative, NaN, or Infinity. Typically reached during layout/render setup when the platform reports an invalid DPI scale, or when a custom render target returns a degenerate scaling value.
Common situations: Headless/server environment where the platform DPI provider returns 0. A misconfigured test environment or mock platform returning NaN. A monitor/reporting edge case on certain Linux/Wayland setups returning unexpected scale. Passing `double.NaN` through a scaling binding.
Related errors
- The control isn't currently attached to a toplevel
- Infinite layout loop detected
- Unable to access .NET memory
- Module.GL object wasn't initialized, WebGL can't be used.
- HTMLCanvasElement.getContext returned null.
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/3aed6d4a49141ae7.
Report an issue: GitHub.