db-sync stuck in crash loop: deeply nested tx metadata causes `stack depth limit exceeded` on `tx_metadata` insert (Preview)
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
Research direction
Start by reading src/Cardano/DbSync/Era/Universal/Insert/Grouped.hs around insertBulkTxMetadataPiped, then trace how decoded metadata is rendered and inserted. The issue suggests checking nesting depth before insertion or handling PostgreSQL SQLSTATE 54001; inspect existing tests for metadata insertion and add coverage for deeply nested valid metadata. Done means syncing continues past block 4821137 while retaining the offending metadata bytes.
Written by the indexing model from the issue text.
Description
Summary
db-sync crashes, and keeps crashing after every restart, while inserting the metadata of block 4821137 on Preview. One transaction in that block carries metadata under label 1 that is a list nested 16,053 levels deep ([[[[…[0]…]]]]). The transaction is valid on-chain because the ledger does not limit metadata nesting depth. When PostgreSQL casts the JSON rendering of that metadata with json::jsonb, it exceeds max_stack_depth. The whole block transaction is rolled back, and db-sync can't get past this block.
Because the transaction is valid, every db-sync instance syncing Preview with tx_metadata enabled and default Postgres settings should hit this.
Environment
- Network: Preview
- cardano-db-sync / PostgreSQL versions: not captured in the log, will add on request
- PostgreSQL
max_stack_depth = 2048kB(default) - Running in a container (podman)
Affected block
- Block:
4821137 - Slot:
127055999 - Block hash:
e5a2152e974d69023be7e7bb8e96141e65d28c2473836285ef06f4575833cb87 - Offending transaction:
ede279c9cf7f9d4bb909f03ae06af5afedada6aaa9ca305c2cd6df3a4fd179e5, metadata label1(db-sync assigned ittx_id7083191 before the rollback)
Error
[db-sync-node:Info:155] [2026-11-04 12:39:01.56 UTC] Received block which is not in the db with HeaderFields {headerFieldSlot = SlotNo 127055999, headerFieldBlockNo = BlockNo 4821137, headerFieldHash = e5a2152e974d69023be7e7bb8e96141e65d28c2473836285ef06f4575833cb87}. Time to restore consistency.
[db-sync-node:Info:155] [2026-11-04 12:39:01.56 UTC] Starting at epoch 1470
[db-sync-node:Error:155] [2026-11-04 12:39:01.61 UTC] Error SNErrDbSessionErr:
App call chain: runDbSyncTransaction at Cardano.DbSync.Default:src/Cardano/DbSync/Default.hs:57
DB call chain: fn:insertBulkTxMetadataPiped md:Cardano.DbSync.Era.Universal.Insert.Grouped loc:src/Cardano/DbSync/Era/Universal/Insert/Grouped.hs:345
ResultError (ServerError "54001" "stack depth limit exceeded" Nothing (Just "Increase the configuration parameter \"max_stack_depth\" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.") Nothing)
QueryError "INSERT INTO tx_metadata (key, json, bytes, tx_id) SELECT key, json::jsonb, bytes, tx_id FROM UNNEST ($1::numeric[], $2::text[], $3::bytea[], $4::bigint[]) AS t(key, json, bytes, tx_id) RETURNING id" [...]
...
cardano-db-sync: Error SNErrDbSessionErr: (same as above, process exits)
The full query parameters are about 114 KB. The relevant parts:
keyarray:[55534473, 721, 674, 55534473, 55534473, 1, 674]tx_idarray:[7083184, 7083185, 7083187, 7083188, 7083190, 7083191, 7083192]- The 6th entry (key
1, tx_id7083191):json:[× 16,053, then0, then]× 16,053 (32,107 characters)bytes:0x81× 16,053 followed by0x00(about 16 KB of CBOR: an array of length 1, nested 16,053 times, around the integer 0)
The other six metadata entries are ordinary small objects and insert fine.
Root cause
- The ledger accepts arbitrarily deep metadata nesting, as long as the transaction fits the size limit. About 16 KB of
0x81bytes gives about 16k levels. - db-sync renders the metadata as JSON text and inserts it with
json::jsonbininsertBulkTxMetadataPiped(Grouped.hs:345). - PostgreSQL's JSON parser is recursive. 16k levels exceed the default 2 MB
max_stack_depth, which raises SQLSTATE54001. - The error isn't handled. The block transaction rolls back, db-sync exits, and on restart it reprocesses the same block. This is a permanent crash loop.
Workarounds
- Whitelist metadata labels so that label
1is skipped:
You can also disable tx_metadata entirely."insert_options": { "tx_metadata": { "enable": true, "keys": [721, 674] } } - Raise
max_stack_depthin PostgreSQL. It must stay below the OS/container stack limit (ulimit -s), so this may also mean raising the container's stack ulimit. This only moves the limit: a deeper payload would break it again.
Suggested fix
db-sync should not crash on valid on-chain data. Possible approaches:
- Check the nesting depth (or the JSON size) of the decoded metadata before the insert. When it is above a safe threshold, store
json = NULLand keep the rawbytes. Thejsoncolumn is already nullable for metadata that can't be represented as JSON. - Or catch SQLSTATE
54001on thetx_metadatainsert, fall back to inserting the offending row withjson = NULL, and log a warning.
Either way, the raw CBOR stays available in bytes and syncing continues.
- Dominant language
- Haskell
- Stars
- 319
- Forks
- 169
- Avg merge
- 10h 54m
- Merged PRs (30d)
- 3
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from IntersectMBO/cardano-db-sync
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
IntersectMBO/cardano-db-sync#1952 · 1 comment ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
IntersectMBO/cardano-db-sync#1645 · 3 comments ·
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 55/100
IntersectMBO/cardano-db-sync#2189 ·
-
pool_relay ipv4/ipv6 stored with literal double quotes in 13.8.0.0Possibly taken A pull request linked to this issue is open or already merged. Openbug
Difficulty 3/5 1-2 days Newbie friendliness 72/100
IntersectMBO/cardano-db-sync#2182 ·
-
question
Difficulty 4/5 3-5 days Newbie friendliness 48/100
IntersectMBO/cardano-db-sync#2172 ·
All issues in IntersectMBO/cardano-db-sync
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
-
15-minutes 5-minutes algorithm any-language beginner-friendly c cpp csharp easy go good first issue hacktoberfest help wanted java javascript kotlin python rust swift typescript
Difficulty 1/5 Under an hour Newbie friendliness 68/100
Huerte/algo-solutions-python#260 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
IntersectMBO/cardano-ledger#6276 ·
Maintainers usually reply within 1 day