SixLabors/ImageSharp · error · DegenerateTransformException
Matrix is degenerate. Check input values.
Error message
Matrix is degenerate. Check input values.
What it means
The AffineTransformProcessor constructor validates that the affine transform matrix is not degenerate — i.e. it collapses space (zero determinant / non-invertible), so no meaningful source-to-destination mapping exists. TransformUtilities.IsDegenerate performs this check and DegenerateTransformException is thrown before any pixels are processed.
Solutions
- Check the matrix before passing it: ensure it has a non-zero determinant (Matrix4x4.GetDeterminant() != 0)
- Fix the source of the matrix — e.g. clamp scale factors away from 0
- Catch DegenerateTransformException and fall back to an identity or last-known-good transform
- Validate concatenated matrices after each append/prepend when building transforms dynamically
Example fix
// before
var matrix = Matrix3x2.CreateScale(scaleX, scaleY); // scaleX == 0 from config
image.Mutate(x => x.Transform(matrix));
// after
if (Math.Abs(Matrix3x2.CreateScale(scaleX, scaleY).GetDeterminant()) < float.Epsilon)
{
throw new InvalidOperationException("Affine matrix is degenerate; check scale factors.");
}
image.Mutate(x => x.Transform(Matrix3x2.CreateScale(scaleX, scaleY))); Defensive patterns
Strategy: validation
Validate before calling
static bool IsNonDegenerate(Matrix4x4 m) => MathF.Abs(m.GetDeterminant()) > 1e-6f;
if (!IsNonDegenerate(matrix)) throw new InvalidOperationException("Affine matrix is degenerate."); Type guard
static bool IsUsableAffineTransform(Matrix4x4 m) => !float.IsNaN(m.GetDeterminant()) && MathF.Abs(m.GetDeterminant()) > float.Epsilon;
Try / catch
try
{
image.Mutate(x => x.Transform(affineMatrix));
}
catch (DegenerateTransformException ex)
{
// fall back to identity or last known good matrix
throw;
} Prevention
- Validate scale factors are non-zero before composing scale transforms
- Check determinant after every matrix concatenation
- Avoid hard-coded matrices; derive them from helpers (CreateScale/CreateRotation/Skew) with clamped inputs
- Add unit tests for each transform source with realistic configuration values
When it happens
Trigger: Creating an AffineTransformProcessor (or calling AffineTransformBuilder-driven Mutate/Transform overloads) with a matrix whose determinant is zero, e.g. a scale of 0 on an axis or a projection onto a line.
Common situations: Building transform matrices from user input or configuration where a scale factor is 0; concatenating matrices that cancel each other out; computing matrices at runtime (from fit-to-size math) that produce a singular result.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Matrix is degenerate. Check input values.
- ANI bitmap resources require a supported bit depth.
- ANI bitmap resources require exactly one color plane.
- Invalid gif colormap size
- Invalid ICC profile.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/175479132daed28c.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor.cs:26
/// <summary>
/// Defines an affine transformation applicable on an <see cref="Image"/>.
/// </summary>
public class AffineTransformProcessor : CloningImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="AffineTransformProcessor"/> class.
/// </summary>
/// <param name="matrix">The transform matrix.</param>
/// <param name="sampler">The sampler to perform the transform operation.</param>
/// <param name="targetDimensions">The target dimensions.</param>
public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targetDimensions)
{
Guard.NotNull(sampler, nameof(sampler));
Guard.MustBeValueType(sampler);
if (TransformUtilities.IsDegenerate(matrix))
{
throw new DegenerateTransformException("Matrix is degenerate. Check input values.");
}
this.Sampler = sampler;
this.TransformMatrix = matrix;
this.DestinationSize = targetDimensions;
}
/// <summary>
/// Gets the sampler to perform interpolation of the transform operation.
/// </summary>
public IResampler Sampler { get; }
/// <summary>
/// Gets the matrix used to supply the affine transform.
/// </summary>
public Matrix3x2 TransformMatrix { get; }
/// <summary>View on GitHub (pinned to 59ce6af6fc)