Merged
Conversation
89d28f0 to
f022315
Compare
chenrui333
approved these changes
Feb 26, 2026
Contributor
|
🤖 An automated task has requested bottles to be published to this PR. Caution Please do not push to this PR branch before the bottle commits have been pushed, as this results in a state that is difficult to recover from. If you need to resolve a merge conflict, please use a merge commit. Do not force-push to this PR branch. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Created by
brew bumpCreated with
brew bump-formula-pr.Details
release notes
?format=takes precedence overAcceptheaderipfs diag datastorecommandsipfs swarm addrs autonatcommandipfs p2ptunnels with foreground modeipfs dag statoutputipfs keyimprovementsContent-Typeheaders for binary responsesipfs name get|putcommandsipfs ls🔦 Highlights
This release brings reproducible file imports (CID Profiles), cleanup of interrupted flatfs operations, better connectivity diagnostics, and improved gateway behavior. It also ships with Go 1.26, lowering memory usage and GC overhead across the board.
🔢 IPIP-499: UnixFS CID Profiles
CID Profiles are presets that pin down how files get split into blocks and organized into directories, so you get the same CID for the same data across different software or versions. Defined in IPIP-499.
New configuration profiles
unixfs-v1-2025: modern CIDv1 profile with improved defaultsunixfs-v0-2015(aliaslegacy-cid-v0): best-effort legacy CIDv0 behaviorApply with:
ipfs config profile apply unixfs-v1-2025The
test-cid-v1andtest-cid-v1-wideprofiles have been removed. Useunixfs-v1-2025or manually set specificImport.*settings instead.New
Import.*optionsImport.UnixFSHAMTDirectorySizeEstimation: estimation mode (links,block, ordisabled)Import.UnixFSDAGLayout: DAG layout (balancedortrickle)New
ipfs addCLI flags--dereference-symlinksresolves all symlinks to their target content, replacing the deprecated--dereference-argswhich only resolved CLI argument symlinks--empty-dirs/-Econtrols inclusion of empty directories (default: true)--hidden/-Hincludes hidden files (default: false)--trickleimplicit default can be adjusted viaImport.UnixFSDAGLayoutipfs files writefix for CIDv1 directoriesWhen writing to MFS directories that use CIDv1 (via
--cid-version=1oripfs files chcid), single-block files now produce raw block CIDs (likebafkrei...), matching the behavior ofipfs add --raw-leaves. Previously, MFS would wrap single-block files in dag-pb even when raw leaves were enabled. CIDv0 directories continue to use dag-pb.Block size limit raised to 2MiB
ipfs block put,ipfs dag put, andipfs dag importnow accept blocks up to 2MiB without--allow-big-block, matching the bitswap spec. The previous 1MiB limit was too restrictive and brokeipfs dag importof 1MiB-chunked non-raw-leaf data (protobuf wrapping pushes blocks slightly over 1MiB). The max--chunkervalue foripfs addis2MiB - 256 bytesto leave room for protobuf framing. IPIP-499 profiles use lower chunk sizes (256KiB and 1MiB) and are not affected.HAMT Threshold Fix
HAMT directory sharding threshold changed from
>=to>to match the Go docs and JS implementation (ipfs/boxo@6707376). A directory exactly at 256 KiB now stays as a basic directory instead of converting to HAMT. This is a theoretical breaking change, but unlikely to impact real-world users as it requires a directory to be exactly at the threshold boundary. If you depend on the old behavior, adjustImport.UnixFSHAMTShardingSizeto be 1 byte lower.🧹 Automatic cleanup of interrupted imports
If you cancel
ipfs addoripfs dag importmid-operation, Kubo now automatically cleans up incomplete data on the next daemon start. Previously, interrupted imports would leave orphan blocks in your repository that were difficult to identify and remove without pins and running explicit garbage collection.Batch operations also use less memory now. Block data is written to disk immediately rather than held in RAM until the batch commits.
Under the hood, the block storage layer (flatfs) was rewritten to use atomic batch operations via a temporary staging directory. See go-ds-flatfs#142 for details.
🌍 Light clients can now use your node for delegated routing
The Routing V1 HTTP API is now exposed by default at
http://127.0.0.1:8080/routing/v1. This allows light clients in browsers to use Kubo Gateway as a delegated routing backend instead of running a full DHT client. Support for IPIP-476: Delegated Routing DHT Closest Peers API is included. Can be disabled viaGateway.ExposeRoutingAPI.📊 See total size when pinning
ipfs pin add --progressnow shows the total size of the pinned DAG as it fetches blocks.Example output:
🔀 IPIP-523:
?format=takes precedence overAcceptheaderThe
?format=URL query parameter now always wins over theAcceptheader (IPIP-523), giving you deterministic HTTP caching and protecting against CDN cache-key collisions. Browsers can also use?format=reliably even when they sendAcceptheaders with specific content types.The only breaking change is for edge cases where a client sends both a specific
Acceptheader and a different?format=value for an explicitly supported format (tar,raw,car,dag-json,dag-cbor, etc.). PreviouslyAcceptwould win. Now?format=always wins.🚫 IPIP-524: Gateway codec conversion disabled by default
Gateways no longer convert between codecs by default (IPIP-524). This removes gateways from a gatekeeping role: clients can adopt new codecs immediately without waiting for gateway operator updates. Requests for a format that differs from the block's codec now return
406 Not Acceptable.Migration: Clients should fetch raw blocks (
?format=raworAccept: application/vnd.ipld.raw)and convert client-side using libraries like @helia/verified-fetch.
Set
Gateway.AllowCodecConversionto
trueto restore previous behavior.✅ More reliable IPNS over PubSub
IPNS over PubSub implementation in Kubo is now more reliable. Duplicate messages are rejected even in large networks where messages may cycle back after the in-memory cache expires.
Kubo now persists the maximum seen sequence number per peer to the datastore (go-libp2p-pubsub#BasicSeqnoValidator), providing stronger duplicate detection that survives node restarts. This addresses message flooding issues reported in #9665.
IPNS over PubSub is opt-in via
Ipns.UsePubsub. Kubo's pubsub is optimized for IPNS use case. For custom pubsub applications requiring different validation logic, use go-libp2p-pubsub directly in a dedicated binary.🗄️ New
ipfs diag datastorecommandsNew experimental commands for low-level datastore inspection:
ipfs diag datastore get <key>- Read raw value at a datastore key (use--hexfor hex dump)ipfs diag datastore count <prefix>- Count entries matching a datastore prefixThe daemon must not be running when using these commands. Run
ipfs diag datastore --helpfor usage examples.🔍 New
ipfs swarm addrs autonatcommandThe new
ipfs swarm addrs autonatcommand shows the network reachability status of your node's addresses as verified by AutoNAT V2. AutoNAT V2 leverages other nodes in the IPFS network to test your node's external public reachability, providing a self-service way to debug connectivity.Public reachability is important for:
The command displays:
Example output:
This helps diagnose connectivity issues and understand if your node is publicly reachable. See the AutoNAT V2 spec for more details.
🚇 Improved
ipfs p2ptunnels with foreground modeP2P tunnels can now run like SSH port forwarding: start a tunnel, use it, and it cleans up automatically when you're done.
The new
--foreground(-f) flag foripfs p2p listenandipfs p2p forwardkeeps the command running until interrupted. When you Ctrl+C, send SIGTERM, or stop the service, the tunnel is removed automatically:Without
--foreground, commands return immediately and tunnels persist until explicitly closed (existing behavior).See docs/p2p-tunnels.md for usage examples.
📊 Friendlier
ipfs dag statoutputThe
ipfs dag statcommand has been improved for better terminal UX:Example progress (interactive terminal):
Example summary output:
Use
--progress=trueto force progress even when piped, or--progress=falseto disable it.🔑
ipfs keyimprovementsipfs key lsis now the canonical command for listing keys, matchingipfs pin lsandipfs files ls. The oldipfs key liststill works but is deprecated.Listing also became more resilient: bad keys are now skipped with an error log instead of failing the entire operation.
🤝 More reliable content providing after startup
Previously, provide operations could start before the Accelerated DHT Client discovered enough peers, causing sweep mode to lose its efficiency benefits. Now, providing waits for the initial network crawl (about 10 minutes). Your content will be properly distributed across DHT regions after initial DHT map is created. Check
ipfs provide statto see when providing begins.🌐 No unnecessary DNS lookups for AutoTLS addresses
Kubo no longer makes DNS queries for AutoTLS addresses like
1-2-3-4.peerid.libp2p.direct. Since the IP is encoded in the hostname (1-2-3-4means1.2.3.4), Kubo extracts it locally. This reduces load on the public good DNS servers atlibp2p.directrun by Shipyard, reserving them for web browsers which lack direct DNS access and must rely on the browser's resolver.To disable, set
AutoTLS.SkipDNSLookuptofalse.⏱️ Configurable gateway request duration limit
Gateway.MaxRequestDurationsets an absolute deadline for gateway requests. UnlikeRetrievalTimeout(which resets on each data write and catches stalled transfers), this is a hard limit on the total time a request can take.The default 1 hour limit (previously hardcoded) can now be adjusted to fit your deployment needs. This is a fallback that prevents requests from hanging indefinitely when subsystem timeouts are misconfigured or fail to trigger. Returns 504 Gateway Timeout when exceeded.
🔧 Recovery from corrupted MFS root
If your daemon fails to start because the MFS root is not a directory (due to misconfiguration, operational error, or disk corruption), you can now recover without deleting and recreating your repository in a new
IPFS_PATH.The new
ipfs files chrootcommand lets you reset the MFS (Mutable File System) root or restore it to a known valid CID:See
ipfs files chroot --helpfor details.📡 RPC
Content-Typeheaders for binary responsesHTTP RPC endpoints that return binary data now set appropriate
Content-Typeheaders, making it easier to integrate with HTTP clients and tooling that rely on MIME types. On CLI these commands behave the same as before, but over HTTP RPC you now get proper headers:/api/v0/getapplication/x-tarorapplication/gzip/api/v0/dag/exportapplication/vnd.ipld.car/api/v0/block/getapplication/vnd.ipld.raw/api/v0/name/getapplication/vnd.ipfs.ipns-record/api/v0/diag/profileapplication/zip🔖 New
ipfs name get|putcommandsYou can now backup, restore, and share IPNS records without needing the private key.
These are low-level tools primarily for debugging and testing IPNS.
The
putcommand validates records by default. Use--forceto skip validation and test how routing systems handle malformed or outdated records. Note that--forceonly bypasses this command's checks; the routing system may still reject invalid records.📋 Long listing format for
ipfs lsThe
ipfs lscommand now supports--long(-l) flag for displaying Unix-style file permissions and modification times. This works with files added using--preserve-modeand--preserve-mtime. Seeipfs ls --helpfor format details and examples.🖥️ WebUI Improvements
IPFS Web UI has been updated to v4.11.0.
Search and filter files
You can now search and filter files directly in the Files screen. Type a name, CID, or file extension and the list narrows down in real time. Works in both list and grid view.
DHT Provide diagnostic screen
New screen under Diagnostics that shows the health of DHT Provide operations. You can see reprovide cycle progress, worker utilization, queue status, and network throughput at a glance, without having to use the
ipfs provide statCLI.Better path handling in Files
The Inspect button now resolves
/ipfs/and/ipns/paths to their final CID before opening the IPLD Explorer. The Explore form also acceptsipfs://andipns://protocol URLs. Previously, these would show a blank screen or an infinite spinner. Path resolution errors now also show better error pages:📉 Fixed Prometheus metrics bloat on popular subdomain gateways
Most Kubo users are unaffected by this change. It matters if you run Kubo as a public subdomain gateway (with
Gateway.PublicGatewaysandUseSubdomains: true), where theotelhttpinstrumentation was including the rawHostheader as theserver_addressmetric label. Every unique hostname (e.g., eachCID.ipfs.dweb.link) created a separate time series, resulting in millions of metric lines, multi-gigabyte/debug/metrics/prometheusresponses, and Prometheus scrape timeouts.What changed:
http_server_*metrics replace the unboundedserver_addresslabel with a newserver_domainlabel that groups requests by gateway domain:Gateway.PublicGatewayssuffix (e.g.,dweb.link,ipfs.io), orlocalhost,loopback,otherapi/ Libp2p Gateway:libp2pIf you use Rainbow for your public gateway (recommended), this issue never applied to you -- Rainbow uses its own low-cardinality HTTP metrics.
📢 libp2p announces all interface addresses
go-libp2p v0.47.0 includes a rewritten routing library (
go-netroute) that fixes interop with VPN and WireGuard/Tailscale setups. A side effect: when listening on0.0.0.0, libp2p now returns addresses from all network interfaces instead of just the primary one (go-libp2p#3460).This means easier connectivity and less manual configuration for most desktop, VPN, and self-hosted users. However, if you don't run with the
serverprofile and have an emptyAddresses.NoAnnounce, your node may now announce internal addresses (e.g. Docker bridge172.17.0.0/16or Tailscale100.64.0.0/10) to the DHT. In the default setup, AutoNAT will probe and mark unreachable ones as offline and they won't be listed, but you can also filter them out explicitly.To check what your node announces and filter out unwanted ranges:
The
serverprofile already filters common private ranges viaAddresses.NoAnnounce.🗑️ Badger v1 datastore slated for removal this year
The
badgerdsdatastore (based on badger 1.x) is slated for removal. Badger v1 has not been maintained by its upstream maintainers for years and has known bugs including startup timeouts, shutdown hangs, and file descriptor exhaustion. Starting with this release, every daemon start with a badger-based repository prints a loud deprecation error on stderr.See the
badgerdsprofile documentation for migration guidance, and #11186 for background.🐹 Go 1.26
This release is built with Go 1.26.
You should see lower memory usage and reduced GC pauses thanks to the new Green Tea garbage collector (10-40% less GC overhead). Reading block data and API responses is faster due to
io.ReadAllimprovements (~2x faster, ~50% less memory). On 64-bit platforms, heap base address randomization adds a layer of security hardening.📦️ Dependency updates
go-libp2pto v0.47.0 (incl. v0.46.0)stream.Close()blocking indefinitely on unresponsive peers (go-libp2p#3448).quic-goto v0.59.0 (incl. v0.58.0 + v0.57.0)p2p-forgeto v0.7.0go-ds-pebbleto v0.5.9github.com/cockroachdb/pebbleto v2.1.4 to enable Go 1.26 supportgo-libp2p-pubsubto v0.15.0go-ipld-primeto v0.22.0boxoto v0.37.0 (incl. v0.36.0)go-libp2p-kad-dhtto v0.38.0 (includes v0.37.1, v0.37.0)ipfs-webuito v4.11.1 (incl. v4.11.0)gateway-conformancetests to v0.10 (incl. v0.9)📝 Changelog
Full Changelog
ipfs name putfor IPNS record republishing (#11199) (ipfs/kubo#11199)swarm addrs autonatcommand (#11184) (ipfs/kubo#11184)go-clockwithtesting/synctest(#11131) (ipfs/kubo#11131)View the full release notes at https://github.com/ipfs/kubo/releases/tag/v0.40.0.