freqtrade/freqtrade · error · OperationalException
Legacy hyperopt results are no longer supported.Please rerun
Error message
Legacy hyperopt results are no longer supported.Please rerun hyperopt or use an older version to load this file.
What it means
Thrown by HyperoptTools._test_hyperopt_results_exist when the results file exists, is non-empty, and has a '.pickle' suffix. Older freqtrade releases stored hyperopt epochs as pickled lists (hyperopt_results.pickle); current versions use a different serialized format, and pickle files are both incompatible and a potential security hazard, so loading is refused outright. The message tells the user the file must be regenerated.
Source
Thrown at freqtrade/optimize/hyperopt_tools.py:137
Stream hyperopt results from file
"""
import rapidjson
logger.info(f"Reading epochs from '{results_file}'")
with results_file.open("r") as f:
data = []
for line in f:
data += [rapidjson.loads(line)]
if len(data) >= batch_size:
yield data
data = []
yield data
@staticmethod
def _test_hyperopt_results_exist(results_file) -> bool:
if results_file.is_file() and results_file.stat().st_size > 0:
if results_file.suffix == ".pickle":
raise OperationalException(
"Legacy hyperopt results are no longer supported."
"Please rerun hyperopt or use an older version to load this file."
)
return True
else:
# No file found.
return False
@staticmethod
def load_filtered_results(results_file: Path, config: Config) -> tuple[list, int]:
filteroptions = {
"only_best": config.get("hyperopt_list_best", False),
"only_profitable": config.get("hyperopt_list_profitable", False),
"filter_min_trades": config.get("hyperopt_list_min_trades", 0),
"filter_max_trades": config.get("hyperopt_list_max_trades", 0),
"filter_min_avg_time": config.get("hyperopt_list_min_avg_time"),
"filter_max_avg_time": config.get("hyperopt_list_max_avg_time"),
"filter_min_avg_profit": config.get("hyperopt_list_min_avg_profit"),View on GitHub (pinned to 1c8edfe4d1)
Solutions
- Delete or move the legacy file: `rm user_data/hyperopt_results/hyperopt_results.pickle`.
- Re-run the hyperopt with the current version to produce a fresh, compatible results file.
- If the old results are important, load them with the old freqtrade version first and export/record the parameters manually.
Example fix
# before: user_data/hyperopt_results/hyperopt_results.pickle exists from old version freqtrade hyperopt-list # after mv user_data/hyperopt_results/hyperopt_results.pickle ~/backup/ freqtrade hyperopt-list
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def is_legacy_results_file(results_file: Path) -> bool:
return results_file.suffix == ".pickle" and results_file.is_file() and results_file.stat().st_size > 0 Try / catch
from freqtrade.exceptions import OperationalException
try:
HyperoptTools.load_filtered_results(results_file, config)
except OperationalException as e:
if "Legacy hyperopt results" in str(e):
archive/delete the .pickle file and rerun hyperopt
else:
raise Prevention
- Clean user_data/hyperopt_results of *.pickle files right after upgrading freqtrade.
- Back up old result files outside user_data so tools never pick them up.
When it happens
Trigger: Running `freqtrade hyperopt-list`, `hyperopt-show`, or resuming hyperopt in a user_data/hyperopt_results directory that still contains a legacy hyperopt_results.pickle from an old installation.
Common situations: Upgrading freqtrade in place without cleaning user_data/hyperopt_results; restoring a backup of results from an old bot.
Related errors
- Holding-average not available. Please omit the filter on ave
- The file with HyperoptTools results is incompatible with thi
- Using analyze-per-epoch parameter is not supported with a Fr
- --hyperopt-filename expects only the filename, not an absolu
- The '{space}' space is included into the hyperoptimization b
AI-assisted analysis of freqtrade/freqtrade@1c8edfe4d1 (2026-08-15).
Data as JSON: /api/errors/703c1330f7ed93bd.
Report an issue: GitHub.