SixLabors/ImageSharp · error · DegenerateTransformException
Matrix is degenerate. Check input values.
Error message
Matrix is degenerate. Check input values.
What it means
ProjectiveTransformBuilder.CheckDegenerate runs before matrices are combined (PrependMatrix, AppendMatrix) and again in BuildMatrix, so any intermediate or final composition of appended transforms that becomes degenerate is rejected early with DegenerateTransformException. This prevents silently producing a transform that maps everything to a line/point.
Solutions
- Validate each Matrix4x4 with Matrix4x4.GetDeterminant() != 0 before Append/Prepend
- Ensure each appended factory produces a valid transform for the actual runtime size (factories receive Size at build time)
- Catch DegenerateTransformException around BuildMatrix since composed matrices can degenerate even if each part is fine
- Reduce the chain to the minimal set of transforms and add them back one at a time to find the offender
Example fix
// before
builder.AppendMatrix(brokenMatrix); // determinant == 0
// after
if (Math.Abs(brokenMatrix.GetDeterminant()) < float.Epsilon)
{
throw new InvalidOperationException("Refusing to append degenerate matrix.");
}
builder.AppendMatrix(brokenMatrix); Defensive patterns
Strategy: validation
Validate before calling
static bool IsNonDegenerate(Matrix4x4 m) => MathF.Abs(m.GetDeterminant()) > 1e-6f;
foreach (var factory in transformFactories)
{
if (!IsNonDegenerate(factory(size))) throw new InvalidOperationException("Degenerate matrix in builder chain.");
} Type guard
static bool IsAppendable(Matrix4x4 m) => MathF.Abs(m.GetDeterminant()) > float.Epsilon;
Try / catch
try
{
var matrix = builder.BuildMatrix(destinationSize);
}
catch (DegenerateTransformException ex)
{
// inspect builder chain; fall back to affine or identity
throw;
} Prevention
- Validate each matrix before Append/Prepend, not only the composed result
- Ensure transform factories produce valid matrices for the actual runtime Size
- Wrap BuildMatrix in try/catch since composition can degenerate even when parts do not
- When chaining many transforms, log each intermediate matrix's determinant to isolate the offender
When it happens
Trigger: Calling AppendMatrix/PrependMatrix with a degenerate Matrix4x4, or appending factories whose composition (evaluated in BuildMatrix) is degenerate — e.g. appending a scale-0 transform or one that nullifies a prior one.
Common situations: Chaining several transform factories where one produces a zero scale; building transforms from user-supplied corner points that are collinear; refactoring builder code and losing a guard on an individual matrix before appending.
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/9ba431744f29ea30.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Processing/ProjectiveTransformBuilder.cs:414
/// <returns>The <see cref="Size"/>.</returns>
internal static SizeF GetTransformedSize(Rectangle sourceRectangle, Matrix4x4 matrix)
=> TransformUtilities.GetRawTransformedSize(matrix, sourceRectangle.Size);
/// <summary>
/// Clears all accumulated transform matrices, resetting the builder to its initial state.
/// </summary>
/// <returns>The <see cref="ProjectiveTransformBuilder"/>.</returns>
public ProjectiveTransformBuilder Clear()
{
this.transformMatrixFactories.Clear();
return this;
}
private static void CheckDegenerate(Matrix4x4 matrix)
{
if (TransformUtilities.IsDegenerate(matrix))
{
throw new DegenerateTransformException("Matrix is degenerate. Check input values.");
}
}
private ProjectiveTransformBuilder Prepend(Func<Size, Matrix4x4> transformFactory)
{
this.transformMatrixFactories.Insert(0, transformFactory);
return this;
}
private ProjectiveTransformBuilder Append(Func<Size, Matrix4x4> transformFactory)
{
this.transformMatrixFactories.Add(transformFactory);
return this;
}
}
View on GitHub (pinned to 59ce6af6fc)