sklearn ConvergenceWarning: lbfgs failed to converge (tested)
ConvergenceWarning: lbfgs failed to converge after 100 iteration(s) means LogisticRegression hit max_iter before the optimizer converged, usually because features are not scaled. In our test, scaling fixed it in 19 iterations; max_iter=10000 also worked but took 2338. Tested on scikit-learn 1.9.1.
1. The warning
import warnings
warnings.simplefilter("always")
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
X, y = load_breast_cancer(return_X_y=True)
clf = LogisticRegression().fit(X, y)
print("n_iter_:", clf.n_iter_, "max_iter:", clf.max_iter)
Output:
/usr/local/lib/python3.15/site-packages/sklearn/linear_model/_logistic.py:599: ConvergenceWarning: lbfgs failed to converge after 100 iteration(s) (status=1):
STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT
Increase the number of iterations to improve the convergence (max_iter=100).
You might also want to scale the data as shown in:
https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
n_iter_i = _check_optimize_result(
n_iter_: [100] max_iter: 100
LogisticRegression uses the lbfgs solver with max_iter=100 by default. On unscaled data (the breast-cancer features are on very different scales) the optimizer hits the limit before converging, so n_iter_ equals max_iter and you get ConvergenceWarning. The model is still returned, but its coefficients are not the optimum.
2. Fix: scale the features (or raise max_iter)
import warnings
warnings.simplefilter("always")
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X, y = load_breast_cancer(return_X_y=True)
pipe = make_pipeline(StandardScaler(), LogisticRegression()).fit(X, y)
print("scaled n_iter_:", pipe[-1].n_iter_)
clf = LogisticRegression(max_iter=10000).fit(X, y)
print("max_iter=10000 n_iter_:", clf.n_iter_)
Output:
scaled n_iter_: [19]
max_iter=10000 n_iter_: [2338]
With StandardScaler in a pipeline the same model converges in 19 iterations, no warning. Raising max_iter also removes the warning, but needed 2338 iterations here: about 120× the work. Scale first; raise max_iter only if a scaled model still warns.
3. Suppress it (when you accept the result)
import warnings
from sklearn.datasets import load_breast_cancer
from sklearn.exceptions import ConvergenceWarning
from sklearn.linear_model import LogisticRegression
X, y = load_breast_cancer(return_X_y=True)
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=ConvergenceWarning)
clf = LogisticRegression().fit(X, y)
print("silenced; n_iter_:", clf.n_iter_)
warnings.filterwarnings("ignore", module="sklearn")
LogisticRegression().fit(X, y)
print("after module='sklearn' filter")
Output:
silenced; n_iter_: [100]
after module='sklearn' filter
Import ConvergenceWarning from sklearn.exceptions and ignore that category inside warnings.catch_warnings(), which keeps other warnings visible. Unlike matplotlib and pandas, scikit-learn attributes this warning to its own module, so module="sklearn" filters do match it (the last fit printed nothing). Note that silencing does not change the result: n_iter_ is still 100.
Related: NumPy RuntimeWarning · suppress matplotlib warnings · suppress pandas warnings.
Frequently asked questions
How do I fix 'lbfgs failed to converge'?
Scale your features (StandardScaler in a Pipeline). If it still warns, raise max_iter, e.g. LogisticRegression(max_iter=1000).
Is the model still usable after a ConvergenceWarning?
It is returned and can predict, but the coefficients are not fully optimized. Fix the convergence before trusting them.
How do I suppress ConvergenceWarning in sklearn?
from sklearn.exceptions import ConvergenceWarning, then warnings.simplefilter('ignore', category=ConvergenceWarning) inside warnings.catch_warnings().
Written with AI assistance. Measured on 2026-10-23 in Docker: python:3-slim (Python 3.15.1) with scikit-learn 1.9.1. Each block was run verbatim and the output pasted unedited. PlainTables is our extension; Python and scikit-learn are free.