freqtrade/freqtrade · warning · RetryableOrderError

Order not found (pair: {pair} id: {order_id}). Message: {e}

Error message

Order not found (pair: {pair} id: {order_id}). Message: {e}

What it means

In fetch_order_emulated (used when the exchange lacks a unified fetchOrder), both fetch_open_order and fetch_closed_order returned ccxt.OrderNotFound, so the order is neither open nor closed on the exchange. The result is RetryableOrderError — freqtrade expects this may resolve shortly (e.g. ordering lag) and retries it.

Source

Thrown at freqtrade/exchange/exchange.py:1692

    def fetch_order_emulated(self, order_id: str, pair: str, params: dict) -> CcxtOrder:
        """
        Emulated fetch_order if the exchange doesn't support fetch_order, but requires separate
        calls for open and closed orders.
        """
        try:
            order = self._api.fetch_open_order(order_id, pair, params=params)
            self._log_exchange_response("fetch_open_order", order)
            order = self._order_contracts_to_amount(order)
            return order
        except ccxt.OrderNotFound:
            try:
                order = self._api.fetch_closed_order(order_id, pair, params=params)
                self._log_exchange_response("fetch_closed_order", order)
                order = self._order_contracts_to_amount(order)
                return order
            except ccxt.OrderNotFound as e:
                raise RetryableOrderError(
                    f"Order not found (pair: {pair} id: {order_id}). Message: {e}"
                ) from e
        except ccxt.InvalidOrder as e:
            raise InvalidOrderException(
                f"Tried to get an invalid order (pair: {pair} id: {order_id}). Message: {e}"
            ) from e
        except ccxt.DDoSProtection as e:
            raise DDosProtection(e) from e
        except (ccxt.OperationFailed, ccxt.ExchangeError) as e:
            raise TemporaryError(
                f"Could not get order due to {e.__class__.__name__}. Message: {e}"
            ) from e
        except ccxt.BaseError as e:
            raise OperationalException(e) from e

    @retrier(retries=API_FETCH_ORDER_RETRY_COUNT)
    def fetch_order(self, order_id: str, pair: str, params: dict | None = None) -> CcxtOrder:
        if self._config["dry_run"]:

View on GitHub (pinned to 1c8edfe4d1)

Solutions

  1. Retry after a short delay — RetryableOrderError exists exactly for eventual-consistency lag
  2. Confirm pair and order_id match the create response exactly
  3. For old orders, query via fetch_closed orders with time window (fetch_orders) instead of single-order fetch
Defensive patterns

Strategy: retry

Try / catch

from freqtrade.exceptions import RetryableOrderError
try:
    order = exchange.fetch_order(order_id, pair)
except RetryableOrderError:
    time.sleep(5)
    order = exchange.fetch_order(order_id, pair)  # eventual consistency on emulated fetch

Prevention

When it happens

Trigger: Calling fetch_order on an exchange like this right after order creation when the exchange has not indexed the order yet; querying a fully expired/culled order; querying a wrong id or wrong pair.

Common situations: Race between create_order and immediate fetch_order on slow exchanges; per-user order-history retention windows dropping old orders; pagination/timeframe limits on fetch_closed_order.

Related errors


AI-assisted analysis of freqtrade/freqtrade@1c8edfe4d1 (2026-08-15). Data as JSON: /api/errors/ee4ee786220d37f2. Report an issue: GitHub.