scipy minimize error: success False, precision loss, maxiter (tested)
scipy.optimize.minimize usually does not raise when it fails: it returns success=False with a message such as "Maximum number of iterations has been exceeded" or "Desired error not necessarily achieved due to precision loss". Below, each message is reproduced, with the fix that made it converge.
1. success=False: read message and status, not just x
scipy.optimize.minimize almost never raises when the optimizer fails. It returns an OptimizeResult with success=False, a numeric status and a message. b1.py triggers the most common ones:
import numpy as np
from scipy.optimize import minimize, rosen
# minimize() rarely raises: it returns success=False plus a message
r = minimize(rosen, np.zeros(5), method="BFGS", options={"maxiter": 10})
print("1:", r.success, r.status, "|", r.message, "| nit", r.nit)
r = minimize(rosen, np.zeros(5), method="BFGS")
print("2:", r.success, r.status, "|", r.message, "| nit", r.nit)
# non-smooth objective: BFGS lands on the answer but reports failure
def f_abs(x):
return abs(x[0] - 2) + abs(x[1] + 1)
r = minimize(f_abs, [0.0, 0.0], method="BFGS")
print("3:", r.success, r.status, "|", r.message, "| x", np.round(r.x, 4))
r = minimize(f_abs, [0.0, 0.0], method="Nelder-Mead")
print("4:", r.success, r.status, "|", r.message, "| x", np.round(r.x, 4))
# constraints that cannot all hold (x >= 2 and x <= 1)
cons = [{"type": "ineq", "fun": lambda x: x[0] - 2},
{"type": "ineq", "fun": lambda x: 1 - x[0]}]
r = minimize(lambda x: x[0]**2, [0.0], method="SLSQP", constraints=cons)
print("5:", r.success, r.status, "|", r.message)
Output (SciPy 1.18.1, NumPy 2.5.4, Python 3.13.5):
1: False 1 | Maximum number of iterations has been exceeded. | nit 10
2: True 0 | Optimization terminated successfully. | nit 40
3: False 2 | Desired error not necessarily achieved due to precision loss. | x [ 2. -1.]
4: True 0 | Optimization terminated successfully. | x [ 2. -1.]
5: False 8 | Positive directional derivative for linesearch
- "Maximum number of iterations has been exceeded." (status 1): the run was cut off. Raise
options={"maxiter": ...}; with the default limit the same problem converges in 40 iterations (line 2). - "Desired error not necessarily achieved due to precision loss." (status 2): BFGS assumes a smooth function. With
abs()in the objective it found the right point but could not prove it. Use a derivative-free method (Nelder-Mead,Powell) for non-smooth objectives, or supply an exact gradient withjac=for smooth ones. It also appears when the objective returns NaN (section 2). - SLSQP with constraints that cannot all hold (here x >= 2 and x <= 1) failed with status 8, "Positive directional derivative for linesearch", not with a message that mentions the constraints. If you see that from SLSQP, check that your constraints are feasible together.
- Always check
if not r.success: print(r.status, r.message)before usingr.x; in line 3,r.xwas correct but flagged, and in other cases it is simply the last point tried.
2. Errors that do raise, and the NaN case
import numpy as np
from scipy.optimize import minimize
def show(label, fn):
try:
r = fn()
print(label, "->", r.success, "|", r.message)
except Exception as e:
print(label, "->", type(e).__name__ + ":", e)
# objective returns an array instead of a scalar
show("A array", lambda: minimize(lambda x: (x - 1)**2, [0.0, 0.0]))
# extra arguments not passed via args=
def f(x, a):
return ((x - a)**2).sum()
show("B no args", lambda: minimize(f, [0.0]))
show("C args", lambda: minimize(f, [0.0], args=(4.0,)))
# 2-D x0
show("D 2-D x0", lambda: minimize(lambda x: (x**2).sum(), np.zeros((2, 2))))
# objective goes NaN outside its domain
def g(x):
return np.sqrt(x[0]) + x[0]
show("E nan", lambda: minimize(g, [1.0]))
show("F bounds", lambda: minimize(g, [1.0], bounds=[(0, None)]))
Output:
A array -> ValueError: The user-provided objective function must return a scalar value.
B no args -> TypeError: f() missing 1 required positional argument: 'a'
C args -> True | Optimization terminated successfully.
D 2-D x0 -> ValueError: 'x0' must only have one dimension.
/tmp/sm408/b2.py:22: RuntimeWarning: invalid value encountered in sqrt
return np.sqrt(x[0]) + x[0]
/tmp/sm408/b2.py:22: RuntimeWarning: invalid value encountered in sqrt
return np.sqrt(x[0]) + x[0]
/tmp/sm408/b2.py:22: RuntimeWarning: invalid value encountered in sqrt
return np.sqrt(x[0]) + x[0]
E nan -> False | Desired error not necessarily achieved due to precision loss.
F bounds -> True | CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL
- "The user-provided objective function must return a scalar value.": your function returned an array. Return a single number, e.g.
((x - 1)**2).sum(). - "missing 1 required positional argument": extra parameters of the objective must be passed with
args=(...)(case C). - "'x0' must only have one dimension.": flatten the starting point with
x0.ravel()and reshape inside the objective. - NaN objective:
np.sqrt(x)stepped to a negative x, NumPy printedRuntimeWarning: invalid value encountered in sqrt, and BFGS stopped with the same "precision loss" message (status 2). Keeping x in its domain withbounds=[(0, None)](L-BFGS-B is chosen automatically when bounds are given) converged to x = 0.
3. Checklist
- Print
r.success,r.status,r.message,r.nit. - Iteration limit: raise
maxiter, or rescale variables so they are of similar size. - Precision loss: look for NaN/inf (run with
np.seterr(all="raise")to find where), non-smooth terms, or an inaccurate gradient; addboundsor switch method. - SLSQP status 8 or similar with constraints: test the constraints alone at a point you know is feasible.
Related: NumPy floating point errors and isclose, numpy polyfit RankWarning.
Frequently asked questions
Why does scipy minimize return success False?
The optimizer stopped without meeting its tolerance: iteration limit, precision loss from NaN or non-smooth objectives, or infeasible constraints. Read r.message and r.status.
What does "Desired error not necessarily achieved due to precision loss" mean?
BFGS could not make progress along its line search, usually because the objective returned NaN, is not smooth, or the gradient is inaccurate.
How do I fix "The user-provided objective function must return a scalar value"?
Make the objective return one number, for example by summing squared residuals.
Written with AI assistance. Measured on 2026-10-23 with SciPy 1.18.1, NumPy 2.5.4 and Python 3.13.5 on Linux. Scripts ran verbatim and the output was pasted unedited. PlainTables is our extension; SciPy is free.