pola-rs/polars · error · NoDataError
empty data from {context}{hint}
Error message
empty data from {context}{hint} What it means
_check_empty (py-polars/src/polars/io/_utils.py:301-312) guards eager readers against zero-byte input: a bytes object, StringIO, BytesIO, local file, or HTTP body that yields an empty buffer raises polars.exceptions.NoDataError when raise_if_empty=True (the default). For StringIO/BytesIO sources whose read position is past the data, the message appends a hint ('buffer position = N; try seek(0) before reading?') pointing at a consumed buffer rather than truly empty data.
Source
Thrown at py-polars/src/polars/io/_utils.py:310
BytesIO(f.read().encode("utf8")),
context=f"{file!r}",
raise_if_empty=raise_if_empty,
)
return managed_file(file)
def _check_empty(
b: BytesIO, *, context: str, raise_if_empty: bool, read_position: int | None = None
) -> BytesIO:
if raise_if_empty and b.getbuffer().nbytes == 0:
hint = (
f" (buffer position = {read_position}; try seek(0) before reading?)"
if context in ("StringIO", "BytesIO") and read_position
else ""
)
msg = f"empty data from {context}{hint}"
raise NoDataError(msg)
return b
def looks_like_url(path: str) -> bool:
return re.match(r"^(ht|f)tps?://", path, re.IGNORECASE) is not None
def process_file_url(path: str, encoding: str | None = None) -> BytesIO:
from urllib.request import urlopen
with urlopen(path) as f:
if not encoding or encoding in {"utf8", "utf8-lossy"}:
return BytesIO(f.read())
else:
return BytesIO(f.read().decode(encoding).encode("utf8"))
def is_glob_pattern(file: str) -> bool:View on GitHub (pinned to df599052da)
Solutions
- If empty input is legitimate, pass raise_if_empty=False and handle the empty result
- Reset buffers before reading: buf.seek(0) - this is what the hint suggests
- Skip empty files upstream: if path.stat().st_size == 0: continue
- Investigate the producer that wrote/downloaded a 0-byte payload
Example fix
# before buf = io.BytesIO(payload) # payload may be b"" df = pl.read_csv(buf) # NoDataError when empty # after buf = io.BytesIO(payload) df = pl.read_csv(buf, raise_if_empty=False) if buf.getbuffer().nbytes == 0 else pl.read_csv(buf)
Defensive patterns
Strategy: validation
Validate before calling
import io
def ensure_non_empty(source) -> None:
if isinstance(source, (io.StringIO, io.BytesIO)):
empty = source.seek(0, io.SEEK_END) == 0 if source.seekable() else False
source.seek(0)
if empty:
raise ValueError("empty input buffer")
elif hasattr(source, "read"):
source.seek(0)
if not source.read(1):
source.seek(0)
raise ValueError("empty input stream")
Try / catch
from polars.exceptions import NoDataError
try:
df = pl.read_csv(source)
except NoDataError:
df = pl.DataFrame() # or skip/flag this file Prevention
- Call buf.seek(0) on any reused StringIO/BytesIO before handing it to polars
- Size-check files (path.stat().st_size == 0) before batch reads
- Catch polars.exceptions.NoDataError specifically, not bare Exception
When it happens
Trigger: pl.read_csv(io.StringIO('')) or pl.read_csv(io.BytesIO()) with defaults; re-reading the same BytesIO twice without seek(0) - the first read moves the position to EOF, so the second read sees 'empty' data and the hint fires; reading a 0-byte file left by a failed upstream job; a URL that returned an empty body.
Common situations: Pipelines where a source system occasionally emits empty extracts; test code reusing one buffer across multiple read calls; HTTP downloads that succeeded status-wise but returned no bytes.
Related errors
- expected a file path; {path!r} is a directory
- cannot describe a DataFrame that has no columns
- __dlpack__
- cannot get buffer length for buffer with dtype {dtype!r}
- the `columns` argument should contain a list of all integers
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/7a748f8ace325190.
Report an issue: GitHub.