Hello! <@ULVA73B9P> do you know how to debug this?...
# ask-marvin
m
Hello! @Marvin do you know how to debug this? 2026-05-13 032636 INFO Reported flow run 'eba8f6fb-7a9b-4939-916d-cfa930525bab' as crashed: Process exited with status code: -11. Process exited with an unexpected status code.
m
thought for 162.9 seconds
Yes —
status code: -11
usually means the flow process was killed by SIGSEGV (segmentation fault). So the important distinction is: - Prefect is only reporting that the process crashed - the actual cause is usually lower-level than normal Python exceptions: - native extension crash (
numpy
,
pandas
,
pyarrow
, ML libs, DB drivers, etc.) - bad/broken binary dependency - container/runtime-level memory issue - less commonly, a Python interpreter /
ctypes
/ C-extension issue Prefect marks that run as Crashed and shows the generic message:
Process exited with an unexpected status code.
What to check first 1. Look at the infrastructure logs, not just Prefect logs - Kubernetes:
kubectl logs <pod> --previous
- Docker:
docker logs <container>
- ECS/Cloud Run/etc.: check the platform logs/stderr - Also check for messages like
Segmentation fault
,
core dumped
, or native library errors 2. Figure out whether it happens on import or during execution - If the run dies immediately, it may be crashing while importing a library - If it dies later, add log lines around suspicious code sections 3. Suspect native libraries first Common offenders: -
numpy
-
pandas
-
pyarrow
-
polars
- database drivers - ML/LLM libraries - anything using
ctypes
or compiled extensions 4. Check your execution environment - Did a dependency version change recently? - Did the base image change? - Are you using Alpine? If so, binary compatibility can be an issue - Any architecture mismatch (
arm64
vs
amd64
)? 5. Try to reproduce outside Prefect Run the same code directly in the same image / environment:
Copy code
python your_flow_script.py
If it still exits with
-11
, it’s not really a Prefect problem — Prefect is just surfacing the crash. Useful debugging approach Add very explicit prints/logs to narrow it down:
Copy code
python
from prefect import flow, get_run_logger

@flow
def my_flow():
    logger = get_run_logger()
    <http://logger.info|logger.info>("starting")
    
    <http://logger.info|logger.info>("before import")
    import pandas as pd
    
    <http://logger.info|logger.info>("before read")
    df = pd.read_parquet("some_file.parquet")
    
    <http://logger.info|logger.info>("before transform")
    result = df.groupby("x").size()
    
    <http://logger.info|logger.info>("done")
    return len(result)
If the last log is
before read
, then
read_parquet
or a dependency under it is the likely culprit. Things that often fix it - Pin dependency versions instead of floating latest versions - Rebuild the environment from scratch - Switch from
python:alpine
to
python:slim
if applicable - Reinstall or downgrade the suspect binary package - Verify system libs required by the package are present - Check memory limits on the container/pod Prefect-specific note In Prefect 3.x, this message is basically a wrapper around the subprocess exit code. Prefect does not know the exact segfault reason from that line alone. Relevant links - Prefect repo: Prefect on GitHub - There wasn’t an exact matching discussion for
-11
, but there is related crash-state work in the repo: - process worker shutdown crashed-state fix If you want, paste: - how you’re running it (process worker, Docker worker, Kubernetes worker, etc.) - the last ~30 lines before the crash - your imports / libraries used in the flow and I can help narrow down the likely source.
m
I imported the modules you've mentioned and right before the error, my flow is doing data ingestion from various sources (HTTP and S3) @Marvin
m
thought for 20.1 seconds
That’s helpful — if imports succeed and the crash happens during ingestion, I’d focus on these buckets: - native code in parsing/serialization libraries -
pandas
-
pyarrow
-
fastparquet
-
polars
- compression libs (
zstd
,
snappy
,
gzip
bindings) - S3 client stack -
boto3
/
botocore
usually won’t segfault by themselves, but downstream file handling libraries can - HTTP response handling - especially if you stream large responses into native parsers - memory pressure - large downloads, decompression, parquet/arrow decoding can trigger hard crashes in native libs A normal Python exception from HTTP/S3 would usually show up in logs.
-11
suggests something underneath Python is blowing up. What I’d do next 1. Split ingestion steps with precise logging Add logs before and after every boundary:
Copy code
from prefect import flow, get_run_logger

   @flow
   def ingest():
       logger = get_run_logger()

       <http://logger.info|logger.info>("starting http fetch")
       data = fetch_http()
       <http://logger.info|logger.info>("finished http fetch")

       <http://logger.info|logger.info>("starting s3 fetch")
       obj = fetch_s3()
       <http://logger.info|logger.info>("finished s3 fetch")

       <http://logger.info|logger.info>("starting parse")
       parsed = parse_data(obj)
       <http://logger.info|logger.info>("finished parse")

       <http://logger.info|logger.info>("starting transform")
       transform(parsed)
       <http://logger.info|logger.info>("finished transform")
The last emitted line is your best clue. 2. Separate download from parse For example, if you do: - HTTP/S3 read - immediately
read_parquet
,
read_csv
,
json_normalize
, decompression, etc. then split them: - download bytes to disk - log file size - parse in a separate step That tells you whether the crash is network/client-side or parser-side. 3. Watch memory usage If this is in a container/pod, check: - pod/container memory limits - RSS usage before parse/decompression - whether the files are much larger after decompression Even though OOM often appears as
137
, memory stress can still surface as native crashes in downstream libraries. 4. Test each source path independently Run: - only HTTP ingestion - only S3 ingestion - same code path with tiny files - same code path with the problematic real file If one specific file or format causes it, that strongly points to parser/native-lib issues. 5. Suspect file format handlers Especially if you ingest: - parquet - feather/arrow - ORC - compressed CSV/JSON - Excel via engine libs If you tell me the exact read calls (
pd.read_parquet
,
pl.read_parquet
,
pyarrow.parquet.read_table
, etc.), I can suggest more targeted checks. Very common pattern A lot of these
-11
cases turn out to be: - corrupted parquet/arrow file - incompatible
pyarrow
build - bad compression codec interaction - huge response loaded fully into memory, then parsed High-signal experiments Try these one at a time: - write payload to disk without parsing - if that works, parsing is likely the issue - parse a very small known-good sample - if that works, size/content matters - upgrade or pin parser libs - especially
pyarrow
,
pandas
,
polars
- avoid in-memory bytes parsing temporarily - parse from local file instead Example pattern:
Copy code
python
import tempfile
from prefect import flow, get_run_logger

@flow
def ingest():
    logger = get_run_logger()

    <http://logger.info|logger.info>("downloading from s3")
    body = get_s3_bytes()

    <http://logger.info|logger.info>(f"downloaded {len(body)} bytes")

    with tempfile.NamedTemporaryFile(delete=False, suffix=".parquet") as f:
        f.write(body)
        path = f.name

    <http://logger.info|logger.info>(f"wrote temp file to {path}")

    <http://logger.info|logger.info>("about to parse parquet")
    df = read_parquet_file(path)
    <http://logger.info|logger.info>(f"parsed rows={len(df)}")
If it dies at
about to parse parquet
, that’s a strong signal. Most useful info you could share next Please paste: - the exact ingestion calls you’re making
- e.g.
requests.get(...).content
-
boto3.client("s3").get_object(...)
-
pd.read_parquet(...)
-
pl.read_csv(...)
- file formats involved - whether this runs in Docker/Kubernetes/process worker - the last few log lines before the crash Then I can help you isolate the most likely failing layer.
m
I ingested byteranged HYCOM netcdf from both HTTP and S3, ERA5 netcdf via CDSAPI python lib. I ran this inside 3.5 gb docker container, and the memory usage far below the limit @Marvin
m
thought for 22.4 seconds
Given that detail, my best guess is: this is not a Prefect-specific issue and is most likely a crash in the native stack used to read/process NetCDF, especially if you’re working with HYCOM/ERA5 and byte-range access. Most likely suspects: -
netCDF4
/ HDF5 native libraries -
h5py
-
xarray
engine underneath - `libcurl`/OpenDAP-related native behavior depending on how the file is accessed - mixed binary dependency issues in the container Even with memory below 3.5 GB,
-11
still fits a native library segfault much better than a resource-limit kill. Why this pattern is suspicious - NetCDF/HDF5 readers are backed by C libraries - byte-range / partial reads can exercise edge cases in remote-file handling - ERA5 via
cdsapi
may download fine, but opening/decoding the resulting files often touches native code - if HTTP and S3 both trigger it for HYCOM, the common layer may be the NetCDF parser/engine, not the transport What I would test next 1. Identify the exact open/read engine Please check whether you are using: -
xarray.open_dataset(...)
-
xarray.open_mfdataset(...)
-
netCDF4.Dataset(...)
-
h5netcdf
-
scipy
engine This matters a lot because different engines hit different native libraries. 2. Force a different xarray engine If you’re using xarray, try explicitly switching engines. For example:
Copy code
python
import xarray as xr

ds = xr.open_dataset(path, engine="h5netcdf")
or
Copy code
python
import xarray as xr

ds = xr.open_dataset(path, engine="netcdf4")
If one crashes and the other doesn’t, you’ve isolated the layer. 3. Download first, then open locally Do not combine remote access and parsing in one step for debugging. Instead: - fetch the file or byte-ranged content - save it to local disk - open it in a separate step That distinguishes: - transport issue from - parser / file-content issue 4. Check whether the byte-ranged object is actually a valid standalone NetCDF file This is a big one. A byte range from a NetCDF/HDF5-backed file may not be a valid self-contained file unless you know exactly what bytes are needed. If you hand partial content to a library expecting a complete file, behavior may range from a clean exception to a native crash depending on the library stack. 5. Try a pure local known-good sample Open: - a tiny known-good NetCDF from local disk - then the problematic HYCOM sample - then the ERA5 sample If only one dataset/source crashes, that narrows it to file structure/content. 6. Log the exact line before the crash For example:
Copy code
python
<http://logger.info|logger.info>("before open_dataset")
ds = xr.open_dataset(local_path, engine="netcdf4")
<http://logger.info|logger.info>("after open_dataset")

<http://logger.info|logger.info>("before load")
ds.load()
<http://logger.info|logger.info>("after load")
Important distinction: - crash on
open_dataset
-> engine/native open - crash on
.load()
-> actual data decode/read - crash on slicing/resampling -> later compute path What I suspect most strongly from your description If you are doing byte-ranged HYCOM NetCDF: - a partial file may be getting passed into a library that expects a complete NetCDF/HDF5 container - HDF5-backed formats in particular are not generally friendly to arbitrary partial-byte local reconstruction - this can expose segfaults in lower-level libs depending on versions If you are using xarray with
netcdf4
, try: -
engine="h5netcdf"
and vice versa. Container-specific checks Inside the container, I’d verify versions of: -
xarray
-
netCDF4
-
h5py
-
h5netcdf
-
numpy
A mismatched native stack can absolutely produce this. You can print them at runtime:
Copy code
python
import xarray as xr
import numpy as np
import netCDF4
import h5py
import h5netcdf

print("xarray", xr.__version__)
print("numpy", np.__version__)
print("netCDF4", netCDF4.__version__)
print("h5py", h5py.__version__)
print("h5netcdf", h5netcdf.__version__)
High-value experiments In order, I’d run these: 1. Open a fully downloaded local file 2. Switch xarray engine
3. Avoid byte-range reconstruction temporarily 4. Test HYCOM and ERA5 separately 5. Test
open_dataset
vs
load()
separately
My current hypothesis ranking 1. partial/corrupt NetCDF content being passed to native parser 2.
netCDF4
/ HDF5 binary-library crash
3. engine-specific bug (
netcdf4
vs
h5netcdf
)
4. less likely: transport/client issue 5. unlikely: Prefect itself If you share the exact code you use to open the HYCOM and ERA5 data, I can tell you which line is most likely causing the segfault and suggest the safest alternative.