Skip to content

fix(gateway): reject internal HAMT shard blocks#1127

Draft
lidel wants to merge 1 commit intomainfrom
fix/gateway-hamt-internal-shard-error
Draft

fix(gateway): reject internal HAMT shard blocks#1127
lidel wants to merge 1 commit intomainfrom
fix/gateway-hamt-internal-shard-error

Conversation

@lidel
Copy link
Member

@lidel lidel commented Mar 25, 2026

Return HTTP 501 instead of rendering a directory listing with broken links when the requested CID is an internal HAMT shard node. This is better than returning partial broken state, and less involved if we had to write custom UI for this.

Complexity

Not a fan, but there seem to be no easy way to detect we are in internal HAMT node.

Detection uses zero-I/O hash prefix alignment check on value links, with a one-block fallback for all-sub-shard nodes (large directories like Wikipedia). The fetched block is cached and reused by the subsequent EnumLinksAsync call, but still,.. not a fan.

Maybe we just.. leave this alone?

Return HTTP 501 instead of rendering a directory listing with broken
links when the requested CID is an internal HAMT shard node.

HAMT path resolution assumes traversal starts at the root shard (hash
bit offset 0). Internal shards expect bits at a deeper offset, so
LookupByString picks the wrong bucket and every link 404s. The
directory listing looks fine because MapIterator walks links
sequentially without hash-based navigation, but every click fails.

Detection uses zero-I/O hash prefix alignment check on value links,
with a one-block fallback for all-sub-shard nodes (large directories
like Wikipedia). The fetched block is cached and reused by the
subsequent EnumLinksAsync call.

Fixes #1126
@lidel lidel force-pushed the fix/gateway-hamt-internal-shard-error branch from b16859e to 3fc7635 Compare March 25, 2026 03:33
@codecov
Copy link

codecov bot commented Mar 25, 2026

Codecov Report

❌ Patch coverage is 34.04255% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.51%. Comparing base (43c30ce) to head (3fc7635).

Files with missing lines Patch % Lines
ipld/unixfs/hamt/hamt.go 40.00% 21 Missing and 3 partials ⚠️
gateway/handler_defaults.go 0.00% 2 Missing and 1 partial ⚠️
gateway/backend_blocks.go 0.00% 1 Missing and 1 partial ⚠️
gateway/backend_car.go 0.00% 1 Missing and 1 partial ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1127      +/-   ##
==========================================
- Coverage   62.56%   62.51%   -0.06%     
==========================================
  Files         261      261              
  Lines       26216    26263      +47     
==========================================
+ Hits        16402    16417      +15     
- Misses       8125     8153      +28     
- Partials     1689     1693       +4     
Files with missing lines Coverage Δ
gateway/errors.go 82.94% <ø> (ø)
gateway/backend_blocks.go 44.73% <0.00%> (-0.19%) ⬇️
gateway/backend_car.go 49.85% <0.00%> (-0.15%) ⬇️
gateway/handler_defaults.go 55.24% <0.00%> (-1.19%) ⬇️
ipld/unixfs/hamt/hamt.go 77.10% <40.00%> (-3.16%) ⬇️

... and 9 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HAMT directory sub-shard: directory listing recurses but links return 404

1 participant