Skip to content

fix(rpc): CARv2 import over HTTP API#11253

Open
lidel wants to merge 2 commits intomasterfrom
fix/carv2-import-over-http-api
Open

fix(rpc): CARv2 import over HTTP API#11253
lidel wants to merge 2 commits intomasterfrom
fix/carv2-import-over-http-api

Conversation

@lidel
Copy link
Member

@lidel lidel commented Mar 26, 2026

Summary

ipfs dag import fails with Error: operation not supported when importing CARv2 files with the daemon running (i.e., over the HTTP API). CARv1 works fine, and CARv2 also works in offline mode.

The root cause is an interface sniffing mismatch between three layers:

  • boxo's File interface was grandfathered from old https://github.com/ipfs/go-ipfs-files. It requires io.Seeker, so ReaderFile implements Seek() BUT returns ErrNotSupported at runtime when the underlying reader (HTTP multipart stream) can't actually seek
  • go-car v2's NewBlockReader checks r.(io.ReadSeeker) to decide how to skip to the CARv2 data payload: the type assertion succeeds because ReaderFile has a Seek method, so it tries to seek
  • The seek call fails at runtime with "operation not supported"

The irony is that go-car already has a fallback for non-seekable readers (discardingReadSeekerPlusByte) that handles forward-only seeking by reading and discarding bytes. It just never gets reached because ReaderFile falsely advertises seek support.

The fix wraps the file in a plain io.Reader + io.Closer before passing it to NewBlockReader, stripping the io.Seeker interface so go-car uses its forward-only fallback.

Test plan

  • Added TestDagImportCARv2 that imports a CARv2 fixture via the daemon (online) and verifies blocks are accessible
  • Test fails without the fix (Error: operation not supported), passes with it
  • Existing TestDag tests still pass

References

lidel added 2 commits March 26, 2026 19:34
Regression test for #9361.
Imports a CARv2 fixture via the daemon (online mode) and verifies
the blocks are accessible. Currently fails with "operation not
supported" due to the multipart reader not supporting seeking.
Strip the io.Seeker interface from the file before passing it to
go-car's NewBlockReader. Over the HTTP API the underlying reader is
a multipart stream that cannot seek, but boxo's ReaderFile advertises
io.Seeker and returns ErrNotSupported at runtime. Hiding the interface
lets go-car fall back to forward-only reading.

Fixes #9361
@lidel lidel added the skip/changelog This change does NOT require a changelog entry label Mar 26, 2026
@lidel lidel changed the title fix(cli): CARv2 import over HTTP API fix(rpc): CARv2 import over HTTP API Mar 26, 2026
@lidel lidel marked this pull request as ready for review March 26, 2026 18:55
@lidel lidel requested a review from a team as a code owner March 26, 2026 18:55
@davidebeatrici
Copy link

@filebase Could you integrate this fix into your backend, please? Thanks in advance!

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

Labels

skip/changelog This change does NOT require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CARv2 imports broken when using the HTTP API

2 participants