EOFError: Ran out of input / EOF when reading a line (tested)

Python raises EOFError when it needs more data and the input has ended. The two messages people hit are EOFError: Ran out of input from pickle.load and EOFError: EOF when reading a line from input(). We measured both on Python 3.13.5.

1. pickle.load: EOFError: Ran out of input

import pickle, os
open("empty.pkl", "wb").close()          # 0-byte file (crashed writer, touch, etc.)
try:
    with open("empty.pkl", "rb") as f:
        pickle.load(f)
except EOFError as e:
    print("empty file:", type(e).__name__, e)

with open("one.pkl", "wb") as f:
    pickle.dump({"a": 1}, f)
with open("one.pkl", "rb") as f:
    print("first load:", pickle.load(f))
    try:
        pickle.load(f)                    # reading past the last object
    except EOFError as e:
        print("second load:", type(e).__name__, e)

data = pickle.dumps(list(range(1000)))
with open("cut.pkl", "wb") as f:
    f.write(data[:len(data)//2])          # truncated write
try:
    with open("cut.pkl", "rb") as f:
        pickle.load(f)
except Exception as e:
    print("truncated:", type(e).__name__, e)

Output:

empty file: EOFError Ran out of input
first load: {'a': 1}
second load: EOFError Ran out of input
truncated: UnpicklingError pickle data was truncated

Measured on Python 3.13.5: "Ran out of input" means pickle.load hit end of file before the first byte of an object. Two causes: the file is empty (0 bytes), or you already read the last object and called load again. A file cut off mid-object gives a different error, UnpicklingError: pickle data was truncated.

2. Why the file is empty

import pickle
f = open("data.pkl", "wb")
pickle.dump([1, 2, 3], f)
# forgot f.close() / flush: another reader opens it now
with open("data.pkl", "rb") as g:
    try:
        print(pickle.load(g))
    except EOFError as e:
        print("before close:", type(e).__name__, e)
f.close()
with open("data.pkl", "rb") as g:
    print("after close:", pickle.load(g))

# opening for writing truncates first, so "w" then read in the same script = empty
open("data.pkl", "wb")
with open("data.pkl", "rb") as g:
    try:
        pickle.load(g)
    except EOFError as e:
        print("after open('wb'):", e)

Output:

before close: EOFError Ran out of input
after close: [1, 2, 3]
after open('wb'): Ran out of input

Measured: pickle.dump writes into Python's buffer; until the file is closed or flushed, a reader sees 0 bytes. Also, open(path, "wb") truncates the file immediately, so opening for write "just to check", or a crash between that open and the dump, leaves an empty file behind. Use with open(...) so the file is closed, and write to a temp file then os.replace() it if a crash mid-write matters.

3. Fixes: load every object, or default on empty

import pickle, os

def load_all(path):
    out = []
    with open(path, "rb") as f:
        while True:
            try:
                out.append(pickle.load(f))
            except EOFError:
                return out

def load_or_default(path, default):
    if not os.path.exists(path) or os.path.getsize(path) == 0:
        return default
    with open(path, "rb") as f:
        return pickle.load(f)

with open("many.pkl", "wb") as f:
    for i in range(3):
        pickle.dump({"n": i}, f)
print(load_all("many.pkl"))
open("empty.pkl", "wb").close()
print(load_or_default("empty.pkl", {}))
print(load_or_default("missing.pkl", []))

Output:

[{'n': 0}, {'n': 1}, {'n': 2}]
{}
[]

To read a file you appended several dumps to, loop until EOFError; that's the documented end-of-stream signal. For a cache file that may be empty or missing, check the size first and fall back to a default rather than catching every EOFError (which would also hide a corrupt file you'd want to know about).

4. input(): EOFError: EOF when reading a line

name = input("name? ")
print("hello", name)

Run with and without stdin:

$ python3 b4.py < /dev/null
EOFError: EOF when reading a line
$ echo Ada | python3 b4.py
name? hello Ada

Measured: input() raises EOFError: EOF when reading a line when stdin has no more data: run with < /dev/null, piped from a command that printed nothing, Ctrl-D (Ctrl-Z Enter on Windows), a CI job, docker run without -i, or an editor "Run" panel that doesn't attach a console. Some online IDEs need you to type input into a separate stdin box before running.

5. Handling missing input

import sys
try:
    line = input("name? ")
except EOFError:
    line = ""                       # no stdin: Ctrl-D, closed pipe, CI, Docker without -i
print("got:", repr(line))
for line in sys.stdin:              # reading every line: loop ends cleanly at EOF
    print("line:", line.rstrip("\n"))

Run with and without stdin:

$ python3 b5.py < /dev/null
name? got: ''
$ printf "Ada\nx\ny\n" | python3 b5.py
name? got: 'Ada'
line: x
line: y

Catch EOFError around input() and use a default, or read with for line in sys.stdin, which just stops at end of input. For scripts that run unattended, take values from command-line arguments (argparse) or environment variables instead of prompting.

Frequently asked questions

What does EOFError: Ran out of input mean in pickle?

pickle.load reached end of file before any object started. We measured it for a 0-byte file and for calling load again after the last object. A file cut mid-object raises UnpicklingError: pickle data was truncated instead.

Why is my pickle file empty?

Usually the writer hadn't closed or flushed it yet (we measured 0 bytes visible before close), or open(path, 'wb') truncated it and the dump never ran. Use with open() and write to a temp file then os.replace().

How do I read multiple objects from one pickle file?

Call pickle.load in a loop and stop on EOFError. We measured three appended dumps loading back as a list of three.

What does EOFError: EOF when reading a line mean?

input() found no more data on stdin. We measured it with stdin from /dev/null; it also happens with Ctrl-D, CI jobs, docker without -i, and IDE run panels without a console.

How do I fix EOFError with input()?

Wrap input() in try/except EOFError with a default, read via for line in sys.stdin, or take arguments with argparse. Make sure the program actually has stdin attached.

Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5 on Linux: pickle.load on an empty file, after the last object, on a truncated file and on an unflushed file; input() with stdin from /dev/null and from a pipe. Every block was run verbatim and its output pasted from that run. Windows consoles and IDE run panels were not tested. PlainHeaders is our extension; everything else here is built-in Python.