You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
load_labels_from_file and load_edges_from_file functions undocumented use of comma as delimiter via PostgreSQL COPY default, causes data corruption on labels and segfault on edges #2449
Describe the bug
Both functions rely on Postgres's COPY command, ag_load_labels.c and ag_load_edges.c share an identical create_copy_options() that only passes two options to BeginCopyFrom (header and format, everything else is default from Postgres).
load_labels_from_file with a pipe-delimited multi-column label CSV file silently corrupts data (correctly since default is comma). The entire line is read as a single field, column names get merged with values into one token, and the result lands in properties as garbage with no error:
id | properties
----------+---------------------------------------------
... | {"__id__": 1, "id|islocatedin_city": "1|5"}
load_edges_from_file with a pipe-delimited file crashes the server. The 4-column edge format requires start_id, start_vertex_type, end_id, end_vertex_type as separate fields. A quick lookup on it shows that with no comma splitting, fields[1] through fields[3] are null, process_edge_row calls trim_whitespace(fields[1]) on a bad pointer, and the server segfaults.
The documentation mentions no delimiter requirement. The example files use comma but this is never stated as a constraint. The header row is handled manually in the loop rather than by COPY itself (HEADER false), so the parsing feels custom, which makes it even less obvious that COPY's delimiter default is silently in effect underneath.
How are you accessing AGE (Command line, driver, etc.)?
psql
What is the command that caused the error?
SELECT load_labels_from_file('graph', 'Label', '/derived/Label.csv'); -- No error, just incorrect parsing.SELECT load_edges_from_file('graph', 'SomeEdge', '/derived/SomeEdge.csv'); -- This segfaults
026-06-29 19:25:56.972 GMT [1] LOG: client backend (PID 64) was terminated by signal 11: Segmentation fault
2026-06-29 19:25:56.972 GMT [1] DETAIL: Failed process was running: SELECT load_edges_from_file('graph', 'SomeEdge', '/derived/SomeEdge.csv');
2026-06-29 19:25:56.972 GMT [1] LOG: terminating any other active server processes
Expected behavior
Depends really, either have a delimiter option just like postgres COPY command options or clarify in documentation + correct error if comma only (instead of segfaulting).
Environment (please complete the following information):
Thanks for the thorough report and root-cause analysis, @AyoubKaz07 — this is valid, and the segfault makes it a must-fix.
Confirming on current master:
create_copy_options() in both ag_load_labels.c and ag_load_edges.c still passes only format + header to BeginCopyFrom, so COPY's default comma delimiter is silently in effect — hence the silent corruption on pipe-delimited label files.
process_edge_row() accesses fields[0]..fields[3] with no check against nfields, so a row that parses into fewer fields (e.g. a pipe-delimited line read as one comma field) dereferences a bad pointer at trim_whitespace(fields[1]) and crashes the backend. Fix segfault and out-of-bounds reads in file loaders on malformed rows #2453 recently added the nfields parameter and hardened malformed-row handling, but this particular access path isn't guarded yet, so the crash still reproduces.
Direction for a fix (all three are worth doing):
Guard process_edge_row (and the label path) on nfields/column count — turn the short-row crash into a clear ereport(ERROR, ...). A reproducible segfault should never be reachable from user input.
Add a delimiter option to create_copy_options(), mirroring PostgreSQL COPY, plumbed through load_labels_from_file / load_edges_from_file so non-comma files are supported explicitly.
Document the delimiter requirement/option on the load functions.
Your analysis already pinpoints the code — if you'd like to open a PR we'd be glad to review; otherwise this is on the list. Either way, thanks for catching it.
Activity
Fix segfault and out-of-bounds reads in file loaders on malformed rows (
Master to pg19 (#2456)
Fix segfault and out-of-bounds reads in file loaders on malformed rows (
gregfelice commentedon Jul 3, 2026
Thanks for the thorough report and root-cause analysis, @AyoubKaz07 — this is valid, and the segfault makes it a must-fix.
Confirming on current
master:create_copy_options()in bothag_load_labels.candag_load_edges.cstill passes onlyformat+headertoBeginCopyFrom, so COPY's default comma delimiter is silently in effect — hence the silent corruption on pipe-delimited label files.process_edge_row()accessesfields[0]..fields[3]with no check againstnfields, so a row that parses into fewer fields (e.g. a pipe-delimited line read as one comma field) dereferences a bad pointer attrim_whitespace(fields[1])and crashes the backend. Fix segfault and out-of-bounds reads in file loaders on malformed rows #2453 recently added thenfieldsparameter and hardened malformed-row handling, but this particular access path isn't guarded yet, so the crash still reproduces.Direction for a fix (all three are worth doing):
process_edge_row(and the label path) onnfields/column count — turn the short-row crash into a clearereport(ERROR, ...). A reproducible segfault should never be reachable from user input.delimiteroption tocreate_copy_options(), mirroring PostgreSQL COPY, plumbed throughload_labels_from_file/load_edges_from_fileso non-comma files are supported explicitly.Your analysis already pinpoints the code — if you'd like to open a PR we'd be glad to review; otherwise this is on the list. Either way, thanks for catching it.
Fix segfault and out-of-bounds reads in file loaders on malformed rows (