microsoft/qlib · critical · IOError

Unable to fetch instruments from remote server!

Error message

Unable to fetch instruments from remote server!

What it means

In client/server mode, after qlib-server returns a dataset-cache URI, qlib mounts the NFS path via `C.dpm.get_data_uri(freq)/<dataset_cache_dir_name>/<uri>` and calls `DiskDatasetCache.read_data_from_cache`. If that read hits an AttributeError (cache file malformed / wrong object layout), it is re-raised as IOError('Unable to fetch instruments from remote server!'), chained from the original cause.

Source

Thrown at qlib/data/data.py:1137

                    "disk_cache": 1,
                },
                msg_queue=self.queue,
            )
            # - Done in callback
            feature_uri = self.queue.get(timeout=C["timeout"])
            if isinstance(feature_uri, Exception):
                raise feature_uri
            get_module_logger("data").debug("get result")
            try:
                # pre-mound nfs, used for demo
                mnt_feature_uri = C.dpm.get_data_uri(freq).joinpath(C.dataset_cache_dir_name, feature_uri)
                df = DiskDatasetCache.read_data_from_cache(mnt_feature_uri, start_time, end_time, fields)
                get_module_logger("data").debug("finish slicing data")
                if return_uri:
                    return df, feature_uri
                return df
            except AttributeError as attribute_e:
                raise IOError("Unable to fetch instruments from remote server!") from attribute_e


class BaseProvider:
    """Local provider class
    It is a set of interface that allow users to access data.
    Because PITD is not exposed publicly to users, so it is not included in the interface.

    To keep compatible with old qlib provider.
    """

    def calendar(self, start_time=None, end_time=None, freq="day", future=False):
        return Cal.calendar(start_time, end_time, freq, future=future)

    def instruments(self, market="all", filter_pipe=None, start_time=None, end_time=None):
        if start_time is not None or end_time is not None:
            get_module_logger("Provider").warning(
                "The instruments corresponds to a stock pool. "
                "Parameters `start_time` and `end_time` does not take effect now."

View on GitHub (pinned to 79633dd950)

Solutions

  1. Retry once with `D.features(..., disk_cache=0)` to bypass the cache path and confirm the data itself is fine.
  2. Check `C.dpm.get_data_uri(freq) / C.dataset_cache_dir_name` is mounted and contains the returned URI.
  3. Align client and server qlib versions (`pip show pyqlib` both sides) and clear the stale dataset cache dir.

Example fix

# before
df = D.features(insts, fields, start, end)  # server + disk_cache path

# after
df = D.features(insts, fields, start, end, disk_cache=0)
Defensive patterns

Strategy: try-catch

Try / catch

try:
    df = D.features(insts, fields, start, end)
except IOError as e:
    if 'Unable to fetch instruments' in str(e):
        df = D.features(insts, fields, start, end, disk_cache=0)  # bypass server cache
    else:
        raise

Prevention

When it happens

Trigger: `D.features(...)` in client mode where the server-generated cache exists but reading it fails — e.g. cache dir name mismatch, NFS mount missing the file, or a cache produced by an incompatible qlib version whose pickle/binary layout changed.

Common situations: Environments where qlib-server version and client qlib version drift; NFS not mounted at the expected point; stale caches after schema changes.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/fb999d84e9ce0ecc. Report an issue: GitHub.