pandas FutureWarning: Downcasting object dtype arrays on .fillna (tested)

FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated means pandas 2 is silently changing an object column to bool or int64 after filling. On pandas 3.1.0 that cast no longer happens. We tested which fixes remove the warning on both versions.

1. The warning on pandas 2, the object dtype on pandas 3

import warnings
import pandas as pd
warnings.simplefilter("always")

s = pd.Series([True, None, False], dtype=object)     # e.g. a flag column with gaps
r = s.fillna(False)
print(r.dtype, r.tolist())

df = pd.DataFrame({"n": [1, None]}, dtype=object)
r = df.replace({None: 0})
print(r["n"].dtype)

Output with pandas 2.3.3:

/w/b1.py:6: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  r = s.fillna(False)
/w/b1.py:10: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  r = df.replace({None: 0})
bool [True, False, False]
int64

Output with pandas 3.1.0:

object [True, False, False]
object

On pandas 2, fillna, ffill, bfill and replace on an object column silently convert ("downcast") the result to bool or int64, and warn that this will stop. pandas 3 has stopped: the values are the same, but the column stays object with no warning. Code that later checks or relies on the dtype can change behaviour after the upgrade.

2. Fix: convert to a real dtype first, or cast explicitly after

import warnings
import pandas as pd
warnings.simplefilter("always")

s = pd.Series([True, None, False], dtype=object)
print(s.astype("boolean").fillna(False).dtype)       # fix 1: real dtype first
n = pd.Series([1, None], dtype=object)
print(pd.to_numeric(n).fillna(0).dtype)              # same idea for numbers

print(s.fillna(False).infer_objects().dtype)         # fix 2: explicit cast after

Output with pandas 2.3.3:

/w/b2.py:10: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  print(s.fillna(False).infer_objects().dtype)         # fix 2: explicit cast after
boolean
float64
bool

Output with pandas 3.1.0:

boolean
float64
bool

The fix that is warning-free on both versions is to give the column a proper dtype before filling: astype("boolean") (nullable boolean), pd.to_numeric. Adding .infer_objects() after fillna, as the warning suggests, gives the right dtype on both versions, but pandas 2 still warns because the warning fires inside fillna before your cast runs.

3. The future.no_silent_downcasting option

import warnings
import pandas as pd
warnings.simplefilter("always")

s = pd.Series([True, None, False], dtype=object)
pd.set_option("future.no_silent_downcasting", True)  # pandas 2 only: opt in to 3.x
print(s.fillna(False).infer_objects().dtype)

Output with pandas 2.3.3:

bool

Output with pandas 3.1.0:

/w/b3.py:6: Pandas4Warning: 'future.no_silent_downcasting' is deprecated, please refrain from using it.
  pd.set_option("future.no_silent_downcasting", True)  # pandas 2 only: opt in to 3.x
bool

On pandas 2, pd.set_option("future.no_silent_downcasting", True) switches to the pandas 3 behaviour and removes the warning; combine it with .infer_objects() where you need the cast. On pandas 3 the option itself is deprecated (Pandas4Warning), so delete it after upgrading. Converting to a real dtype first (section 2) avoids needing it at all.

Related: all pandas 3 breaking changes · FutureWarning: concat with empty or all-NA entries · to_datetime errors='ignore' deprecated · SettingWithCopyWarning.

Frequently asked questions

How do I fix 'Downcasting object dtype arrays on .fillna is deprecated'?

Convert the column to a real dtype before filling, e.g. s.astype('boolean').fillna(False) or pd.to_numeric(s).fillna(0). That is warning-free on pandas 2 and 3.

Does .infer_objects() remove the warning?

Not on pandas 2: the warning is raised inside fillna before infer_objects runs. It does give the right dtype on both versions.

What does future.no_silent_downcasting do?

On pandas 2 it opts in to the pandas 3 behaviour (no silent cast, no warning). On pandas 3 the option is deprecated and emits Pandas4Warning.

Written with AI assistance. Measured on 2026-10-23 in the python:3-alpine Docker image (Python 3.14) with pandas 2.3.3 and pandas 3.1.0. Each block was run verbatim on both versions with warnings.simplefilter("always") and the output pasted unedited. PlainHeaders is our extension; Python and pandas are free.