numpy.linalg.LinAlgError: Singular matrix (tested causes and fixes)

numpy.linalg.LinAlgError: Singular matrix means np.linalg.inv or solve got a square matrix with linearly dependent rows (determinant 0), so there is no unique answer. In practice it is usually a duplicated or collinear column in a regression. Below: how to confirm it, why nearly singular matrices slip through, and the fixes, tested on NumPy 2.5.4.

1. The error

import numpy as np

A = np.array([[1.0, 2.0], [2.0, 4.0]])   # row 2 = 2 * row 1
print("det:", np.linalg.det(A), "rank:", np.linalg.matrix_rank(A))
try:
    np.linalg.inv(A)
except np.linalg.LinAlgError as e:
    print("LinAlgError:", e)
try:
    np.linalg.solve(A, np.array([1.0, 2.0]))
except np.linalg.LinAlgError as e:
    print("LinAlgError:", e)

Output:

det: 0.0 rank: 1
LinAlgError: Singular matrix
LinAlgError: Singular matrix

A square matrix is singular when its rows (or columns) are linearly dependent: here row 2 is twice row 1, so the determinant is 0 and the rank is 1 instead of 2. Such a matrix has no inverse, and A x = b has either no solution or infinitely many, so both inv and solve raise LinAlgError: Singular matrix. Check np.linalg.matrix_rank(A) to confirm: rank below the size means singular.

2. Nearly singular matrices do not raise

import numpy as np

B = np.array([[1.0, 2.0], [1.0, 2.0 + 1e-15]])   # nearly singular
print("det:", np.linalg.det(B), "cond:", np.linalg.cond(B))
x = np.linalg.solve(B, np.array([1.0, 2.0]))     # no error...
print("x:", x)                                   # ...but huge, meaningless values

Output:

det: 8.881784197001244e-16 cond: 1.5922629181314436e+16
x: [-2.25179981e+15  1.12589991e+15]

A matrix that is singular only up to rounding error passes without an error, but the result is garbage: the condition number is about 1.6e16 and the solution is in the 1e15 range. If np.linalg.cond(A) is near 1/np.finfo(float).eps (about 4.5e15), treat the matrix as singular. The fact that an error appears or not is therefore not a reliable test; a tiny change in the data can flip it.

3. Regression: duplicate or collinear columns

import numpy as np

# regression design matrix with a duplicated column
X = np.column_stack([np.ones(4), [1, 2, 3, 4], [2, 4, 6, 8]]).astype(float)
y = np.array([3.0, 5.0, 7.0, 9.0])
try:
    np.linalg.inv(X.T @ X) @ X.T @ y
except np.linalg.LinAlgError as e:
    print("LinAlgError:", e)

coef, res, rank, sv = np.linalg.lstsq(X, y, rcond=None)
print("lstsq:", coef.round(4), "rank:", rank)
print("pinv: ", (np.linalg.pinv(X) @ y).round(4))

Output:

LinAlgError: Singular matrix
lstsq: [1.  0.4 0.8] rank: 2
pinv:  [1.  0.4 0.8]

The most common real-world cause: a design matrix with a column that is a multiple of another (here column 3 = 2 × column 2), a constant column plus a full set of one-hot dummies, or more columns than rows. X.T @ X is then singular. Fix the data by dropping the redundant column (or one dummy per category, pd.get_dummies(..., drop_first=True)), or use np.linalg.lstsq / np.linalg.pinv, which return the minimum-norm least-squares solution and report the rank (2 here, not 3).

4. Other cases

import numpy as np

C = np.zeros((2, 2))
try:
    np.linalg.inv(C)
except np.linalg.LinAlgError as e:
    print("LinAlgError:", e)
try:
    np.linalg.inv(np.ones((2, 3)))
except np.linalg.LinAlgError as e:
    print("LinAlgError:", e)
print(np.linalg.inv(np.array([[1, 2], [3, 4]])))   # ints are fine

Output:

LinAlgError: Singular matrix
LinAlgError: Last 2 dimensions of the array must be square
[[-2.   1. ]
 [ 1.5 -0.5]]

An all-zero matrix (often a bug upstream: an empty selection or a wrong variable) is singular too. A non-square matrix gives a different LinAlgError: "Last 2 dimensions of the array must be square"; use pinv or lstsq for those. Integer matrices are converted to float automatically and are not a cause.

5. Checklist

Related: NumPy RuntimeWarning (divide by zero, overflow) · assignment destination is read-only · numpy has no attribute 'int'.

Frequently asked questions

What does 'Singular matrix' mean in NumPy?

The matrix has linearly dependent rows or columns (determinant 0, rank below its size), so it has no inverse and solve() has no unique solution.

How do I fix a singular matrix in linear regression?

Remove the duplicated or collinear column (or one dummy per category), or use np.linalg.lstsq / np.linalg.pinv, which handle rank-deficient matrices.

Why does a nearly singular matrix not raise an error?

Rounding makes the determinant tiny instead of 0, so NumPy solves it, but the result is meaningless. Check np.linalg.cond(A); values near 1e16 mean singular in practice.

Written with AI assistance. Measured on 2026-10-23 in Docker: python:3-alpine (Python 3.14.7) with numpy 2.5.4. Each block was run verbatim and the output pasted unedited. PlainTables is our extension; Python and NumPy are free.