python/cpython · error

read too short: got %ld instead of %ld bytes

Error message

read too short: got %ld instead of %ld bytes

What it means

Build-time error from Programs/_freeze_module.c: fread() returned fewer bytes than the stat-reported file size. The file changed (shrank) between fstat and fread, or the read was truncated, so the freezer aborts rather than compiling a partial source file.

Source

Thrown at Programs/_freeze_module.c:112

    struct _Py_stat_struct stat;
    if (_Py_fstat_noraise(fileno(infile), &stat)) {
        fprintf(stderr, "cannot fstat '%s'\n", inpath);
        fclose(infile);
        return NULL;
    }
    size_t text_size = (size_t)stat.st_size;

    char *text = (char *) malloc(text_size + 1);
    if (text == NULL) {
        fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size);
        fclose(infile);
        return NULL;
    }
    size_t n = fread(text, 1, text_size, infile);
    fclose(infile);

    if (n < text_size) {
        fprintf(stderr, "read too short: got %ld instead of %ld bytes\n",
                (long) n, (long) text_size);
        free(text);
        return NULL;
    }

    text[text_size] = '\0';
    return (const char *)text;
}

static PyObject *
compile_and_marshal(const char *name, const char *text)
{
    char *filename = (char *) malloc(strlen(name) + 10);
    if (filename == NULL) {
        return PyErr_NoMemory();
    }
    sprintf(filename, "<frozen %s>", name);
    PyObject *code = Py_CompileStringExFlags(text, filename,

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Make the generating step a build dependency that completes before _freeze_module runs (fix dependency ordering in Makefile)
  2. Rerun the build once the file is stable
  3. Move the build to a local filesystem if it happens on NFS/SMB
  4. Check dmesg/Disk health and free space if short reads persist
Defensive patterns

Strategy: retry

Validate before calling

# shell: wait until the generated input stops changing before freezing
# before=$(stat -c %s "$IN"); sleep 1; after=$(stat -c %s "$IN")
# [ "$before" = "$after" ] || exit 1

Prevention

When it happens

Trigger: The input file is being written concurrently (generated source not finished when the freezer ran); sparse/pseudo files whose stat size does not match readable bytes; disk-full or I/O errors causing a short read.

Common situations: Racing build systems that start freezing while a generator still writes the .py; files on network filesystems with inconsistent size vs data; flaky disks.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/ecc87ab877b37fa6. Report an issue: GitHub.