OUT NOW: FrostWire 7.1.0 for desktop, with distributed torrent search

FrostWire 7.1.0 for desktop turns Distributed Search into something you can rely on. Your computer can now find torrents that other FrostWire users are sharing, browse everything a person shares, and download straight from them, all without a central server. It also brings YouTube downloads with sound, a smarter search, a new identity and backup screen, and a long list of security and stability fixes.

What’s new

Distributed Search that finds more, faster

FrostWire users now form a network that searches together. Your search reaches computers and phones that only share files (and don’t help relay searches for others), which were previously missed. Results are signed by the person sharing them, answers from the mesh follow the live connection when a phone changes network, and the app stays responsive even when the network is busy. Finding the network is faster and more dependable too: FrostWire checks the dedicated IceBridge servers first, tries many peers at once instead of one by one, remembers which ones are dead, and always knows one built-in server to fall back on. Computers on the same home or office network now find each other directly, even though a router will not let them connect through their shared public address.

Browse what other people share

Right-click a Distributed Search result and choose Browse Shared Torrents to see everything that person is sharing, then download any of it straight from them. Results from people who share their catalog also show a Browse icon in the Actions column, so you do not have to find the menu. You can also open it from Tools > Browse Shared Torrents. The icon appears for results from peers running FrostWire 7.1.0 or Android 3.2.2 or newer.

Signature: boUcPuRatTn7eB4Ox/wStwfaC2k2s8f2HlZhohFQhMDezHSFu4PRWTHbUc/gTzaKnhBl49bSff5H496xbanx3L3dnsSk6rHHFVYNUKNm1CgeEg4eC9iyPsD3+boFSg7odkIqRwYaHZAjOgLXO/BiZg4tLYqdJV+RyDrzZINGZjJDAyd/9y+49cgrqvvQj99d54GaYGqI7JxwS8hl6BHVxHe7f+tYMTXsSTabaNyAyCf5k7fDB2zCdkrLreQIqG3mex/1nYdQtYyDcc0klLouLodFJE6LtSkLn/HmRrMpBUUDrb13bJy2uu/dERCxW/uDJa/8vMvWAhvl3Wbgi4LjSw9HpE2yGOImmSwgv/mNNa6DxDuYQwj/If/Dq+/3fLmiquTrdO+c6yUHRTbwtPecIGblfE3Tcl1irmcWTdvf/P1gFRapG8jhzLetkXnLYbwcl5R7sUT92FAoLC9ez9s2vVGRrYUcayQ/s4Z+WdO+Uh1k/tsITn/Hpqg8O8sGdRGYrSGM22OtlStkq/tEY+xfM8wKlr0yGNngUr9uxYee82zgy6lK7TfTplXp5ew8SZDZPaQhRM3KljtZsfgHr3X6ekAKSDhQTXnYCM4httyLDrPM4sxKKRfDYx83bvgqGLbUwpYFPI6SFhNTKonw9MGoHFW9AyhOJbuEW/ctN0Q0nMvEgbaaxrdtu6xOWtw9XtNV

Seeding is publishing, and you are in control

A new page in the setup wizard explains that seeding a torrent makes it discoverable on the BitTorrent network, and gives you two separate choices, both on by default:

  • Join the IceBridge network. You can use Distributed Search, and people searching can find the torrents you are actively seeding by keyword, whether or not you share your catalog.
  • Share my catalog. People can browse everything you are actively seeding, and crawlers can index it. This is only available while you are on the network.

Only torrents you are actively seeding are ever shared. Your download history, paused transfers and private torrents are never published. You can change either choice in the setup wizard or in Tools > Options > IceBridge.

YouTube videos now play with sound

Videos that YouTube serves as separate video and audio streams are now downloaded together and merged automatically, so what you save has sound. If something goes wrong, you still keep the silent video.

Smarter search

  • Search now also matches file names inside a torrent, so looking for readme.txt can find torrents that don’t mention it in their title.
  • Bitsearch joins the list of search engines.
  • Seeds and Size columns now sort as numbers (436 seeds ranks above 64).
  • The dead Idope engine was removed and the default tracker list was refreshed with trackers that actually respond.

Your identity, with a backup you can write on paper

Options > Identity shows your node ID, karma and shared torrents, and lets you back up your identity as a 24-word recovery phrase, restore it, and export or import the identity file. New Karma, Peers and Shared Torrents screens show what the network knows about you and your neighbors.

Tools for power users

  • Tools > IceBridge Console: a live, filterable log of what the distributed search network is doing.
  • The built-in MCP server (off by default, and it only listens on your own computer) can now observe and control IceBridge, so AI assistants can inspect peers, metrics and your local index.
  • Transfer details can recheck local data with a progress bar, toggle sequential download, and add trackers safely.
  • The IP Filter now understands P2P, DAT, CIDR and Hosts block lists, including ZIP files.
  • Powered by jlibtorrent 2.0.12.9, with new NAT-PMP and multiple-connection controls in Advanced BitTorrent settings.

Meet IceBridge: the network layer under Distributed Search

7.1.0 is the first desktop release where FrostWire talks to other FrostWire users directly through IceBridge, a small peer-to-peer network layer built into the app. If BitTorrent is how files move, IceBridge is how FrostWire users talk to each other about them.

What it does. Every install gets its own cryptographic identity (the one you can back up with a 24-word phrase). IceBridge uses that identity to open authenticated, reliable connections over UDP with other FrostWire users, finds them through the BitTorrent DHT (no central server), the local network, and a short list of servers it already knows, and keeps working for people behind routers and phone networks by letting willing peers help each other connect. Desktop computers and the Android app (3.2.2) join the same network.

Where it sits. IceBridge sits underneath search and on top of the networking you already use:

FrostWire (search window, downloads, transfers)
|
Distributed Search -- signed questions and answers about torrents
|
IceBridge -- identity, peers, routing, delivery
|
UDP + BitTorrent DHT

IceBridge never looks inside the messages it carries, and it never moves your files; BitTorrent still does that. Distributed Search is simply the first thing built on it. Alongside search, it already carries the small “who has what” summaries that make routing smart, and the shared-torrent catalogs that power Browse Shared Torrents.

You are in control. IceBridge can be turned off in the settings, you choose whether your active seeds can be browsed, and your download history is never shared. Its local control interface only listens on your own computer and requires a secret token. Power users can also run IceBridge on their own server as a standalone forwarder to help the network (see ICEBRIDGE.md in the repository).

Where it could go. Because IceBridge is deliberately generic, each kind of message is labeled with a protocol number, and the code already reserves slots for things such as chat between peers, publish/subscribe channels, exchanging torrent metadata, file synchronization, node health reports, and AI-assisted tools. These are ideas we are exploring, not promises or dates. The point is that new peer-to-peer features can be added without building a new network each time, and without a company’s servers in the middle.

Compatibility, ports and firewalls

For network admins, hackers and anyone running a strict firewall:

  • Peers are verified over UDP. Peers used to be checked on a separate TCP “identity port”. They are now verified with the same authenticated rUDP handshake the network already uses (Ed25519 keys), so a peer that can be reached over UDP can be found, and no inbound TCP port is needed. The identity port setting is gone. Older versions (desktop 7.0.x and earlier, Android 3.2.1 and earlier) only announce a TCP port, so they and 7.1.0 / Android 3.2.2 do not discover each other through the DHT. Please update both.
  • UDP mesh port. Each install picks its own UDP port automatically (setting ICEBRIDGE_RUDP_PORT, 0 means automatic) so several computers behind one router no longer fight over 6889, and announces the real port on the DHT. Standalone forwarders and the built-in seed use UDP 6889.
  • Built-in seed. virginia1.frostwire.com:6889 is always tried when looking for the network. Override it with -Dfrostwire.icebridge.seeds=host:port,... (an empty value disables it).
  • LAN beacon. Every 10 seconds FrostWire multicasts its rUDP port to 239.255.70.88, UDP 6890, and listens for other nodes. Only private IPv4 senders are believed, nothing is ever answered, and every address it finds still has to pass the rUDP identity handshake before it is trusted. Android 3.2.2 does the same on Wi-Fi.
  • Local control API. The IceBridge control HTTP port listens on 127.0.0.1 only and requires an X-IceBridge-Token header on everything except /health.
  • Firewalls. The installers do not add firewall rules. If a firewall blocks inbound UDP, allow FrostWire’s UDP port so other people can reach you; outgoing connections work either way. On a server running a standalone forwarder, open UDP 6889.
  • Debugging. Use Tools > IceBridge Console or the control API /metrics endpoint. Standalone forwarder setup is in ICEBRIDGE.md in the repository.

Security and safety

This release includes a broad security hardening pass over the distributed search network:

  • Signatures: signed search results now also cover the matched file name, which a man-in-the-middle could previously alter. Responses and registrations use length-prefixed canonical forms.
  • Authentication: the local control interface needs a secret token; unauthenticated rUDP application packets are rejected; relayed messages and hole-punch requests need an authenticated session that matches the claimed sender.
  • Replays and abuse: rUDP handshakes carry a timestamp and stale ones are rejected, a timestamp-skew bypass was fixed, ingress is rate-limited before any signature is verified, sessions are capped (including per /24), and servers rate-limit abusive peers and catalog browsing per verified requester.
  • Denial of service: a crafted fragment index that could force a multi-billion-iteration loop was fixed, oversized or truncated payloads are rejected, HTTP bodies are capped (16 MB for search, 32 MB for torrents), and search results and queries are validated and sanitized.
  • IP filter: block lists that were silently being allowed now really block (#1291).
  • TLS: hostname checks use suffix matching instead of substring matching.
  • Debug ports: release builds no longer expose JMX or JDWP listeners.
  • Privacy: crawler data stays anonymous; presence is stored as hashed endpoints and catalogs by publisher peer id only, never IP addresses.

Fixes you may notice

  • macOS: the app no longer crashes at startup when an old link handler fails to load, rich file icons are back, file icons no longer stall the window, VPN detection no longer reports a VPN that is off, and installers now sign the embedded networking libraries, so they pass Apple’s checks.
  • Linux (Wayland): opening the Transfers tab no longer freezes or crashes the app.
  • Torrents: restarting no longer restores torrents at 0%, files you share from a finished download are saved correctly, and sharing a file that no longer exists is refused with a clear message.
  • Transfers: buttons stop flickering, rows refresh only when they change, and the Files tab keeps your selection and shows live progress.
  • Translations: the new screens and the setup wizard are translated into most of our 57 languages. Fourteen (Breton, Persian, Finnish, Irish, Galician, Hungarian, Icelandic, Lithuanian, Macedonian, Maltese, Norwegian Nynorsk, Punjabi, Slovak and Serbian Latin) still show the new text in English. Translators are welcome.
  • Many other search, YouTube and IP Filter reliability fixes. See the full list below.

By the numbers: how this release got built

7.1.0 is also the product of a very different way of working. Since 7.0.4 (April 20, 2026), the shared common and desktop code was developed by one maintainer directing AI coding agents, with an automated test suite as the referee. Figures below cover only common/ and desktop/ (the Android app has hundreds more commits of its own) and come straight from the git history.

PeriodApr 20 to Oct 8, 2026 (170 calendar days)
Days with commits83 (about every other day)
Commits1,077 (about 13 per active day, 6 per calendar day)
Code added (Java, Kotlin, Gradle, scripts)~127,900 lines written, ~37,800 removed along the way
Code in the final diff+104,600 / -14,500 lines, +90,100 net
Of which tests~38,500 lines, 203 new test classes, about 1,370 new tests
New Java files408
Documentation and plans~7,900 lines of Markdown/text added
Translations61 language files refreshed
Average outputabout 1,100 net lines per active day (about 530 per calendar day)

Who wrote it. About a third of the commits (366) carry the name of the model that did the work in their message. The ones that say so: DeepSeek V4.1 Flash (185 commits), Grok 4.6 (51), Grok 4.7 (36), GPT-6 Sol (30), Claude Sonnet 5.5 (23), Muse Spark 1.3 (21), GPT-6.1 Sol (17), and GPT-6 Luna (3). The rest were committed without a model label. Model credits were recounted on October 10, after we corrected some commit labels that had been copied from older commits; the other figures in the table were measured on October 8. The maintainer chose what to build, reviewed the results, and used the 1,400-test suite and the CI builds to decide what was good enough to keep.

How much human work is that? The commit timestamps cluster into about 135 to 160 working sessions, roughly 135 to 185 hours of active work over the whole period (about two hours per active day). That is a lower bound, since agents think and run tests between commits, but it is the time a person was actually in the loop.

To estimate what the same result would cost without the agents, we used a deliberately generous rate for careful, tested, security-sensitive protocol code: 100 to 200 finished lines of code per developer per day. At that rate, 104,600 lines is about 520 to 1,050 developer-days, or roughly 4,200 to 8,400 hours, which is 2 to 4 developer-years, before design docs, reviews, and the translations. Compared with 135 to 185 hours of actual work, that is something like a 20x to 60x speedup.

These are estimates, not measurements, and lines of code is a blunt tool: many of those lines are tests and mechanical changes, and the rate varies a lot between developers. But the direction is not subtle. A distributed, signed, NAT-traversing search network with a full UI, a security pass, and a test suite used to be a multi-year, multi-person project. This time it shipped in under six months.

Installers for macOS (Intel and Apple Silicon), Linux (x86_64 and arm64) and Windows are attached below.

Full changelog

  • new:Computers on the same network find each other — nodes multicast their rUDP port on the LAN, since the public address the DHT reports cannot be reached from inside the same router
  • new:Distributed search results from peers that share their catalog show a “Browse Shared Torrents” icon in the Actions column, so browsing a peer’s catalog no longer depends on discovering the right-click menu
  • new:Browse the torrents a peer shares — right-click a Distributed search result whose holder allows crawling (“Browse Shared Torrents”) to list everything that peer is sharing, download any of it straight from that peer, or copy its magnet; also available from Tools → Browse Shared Torrents and the IceBridge Console
  • fix:The “Seeding & Publishing” setup page and Tools > Options > IceBridge now separate two choices: joining the IceBridge network (you can search, and anyone searching can find the torrents you are seeding by keyword, whether or not you share a catalog) and sharing your catalog (people can browse everything you are actively seeding and crawlers can index it); unchecking the catalog no longer reads as hiding from search, and sharing the catalog is disabled while you are off the network
  • new:Seeding is publishing — a new setup-wizard page explains that seeding a torrent makes it discoverable on the BitTorrent network, and lets you opt out (on by default) of having the torrents you are actively seeding browsable by the network’s crawlers
  • fix:Peers are now verified over rUDP instead of a TCP identity port, so a peer behind NAT that can be reached over UDP can be found; the DHT announces the rUDP port, servers and phones no longer need an open TCP port, and the “Relay listen port (identity)” setting is gone (peers on older versions that only announce a TCP port are not discovered)
  • new:IceBridge distributed search architecture — FrostWire now launches a local IceBridge daemon (standalone rUDP relay servent) that provides a reliable, fragmented, authenticated mesh transport between peers. The DistributedSearchPerformer sends signed search requests through the daemon’s HTTP control API; the daemon routes them over rUDP to remote peers’ daemons, which process them and send signed responses back. A single poller thread drains the daemon’s /poll endpoint and dispatches payloads to all registered listeners
  • new:YouTube video downloads now play with sound — DASH video-only rows auto-fetch a hidden m4a/Opus sibling and merge it (pure-Java MP4 restitch or WebM remux, same-container pairs only); sibling fetch retries with resume on throttled connections; any failure keeps the silent video
  • new:Tools → IceBridge Console — a live, filterable IceBridge/distributed-search event log (filter by level, category, text, or peer; pause, clear, save, copy)
  • new:Identity settings screen (Options > Identity) — displays node ID, fingerprint, public key, identity difficulty (leading zero bits), karma score, and shared torrent count. Buttons: Show Seed Phrase (24-word BIP39 mnemonic with copy-to-clipboard), Restore from Seed Phrase, Export Identity File, Import Identity File, Copy Fingerprint. Restore and import create a .bak backup before overwriting and trigger a restart
  • new:BIP39 mnemonic support for identity backup — com.frostwire.crypto.Bip39Mnemonic encodes/decodes the 32-byte Ed25519 seed as a 24-word mnemonic using the standard BIP39 English wordlist with SHA-256 checksum. Enables offline paper backup of FrostWire identities
  • new:Identity settings — Initialize Identity button with off-EDT proof-of-work mining (progress bar) and restart; import/restore/export now use the same libtorrent/identity.dat path as the relay stack
  • new:The MCP server now exposes IceBridge observability and control — logs query/tail/clear, relay metrics, peer list/remove/block, local index list/search, digest status, host-cache list/ping/add, remote relay logs, MCP status/control, and IceBridge settings via settings get/set
  • new:File-level search indexing — individual file paths within torrents are now indexed in a separate shared_files FTS5 table, enabling search matches on file names (e.g. “readme.txt”) even when the torrent name doesn’t contain the query. Search results that match on a file path populate the matchedFile field, surfaced as the result filename in the UI
  • new:Local search (and remote answers from this node) only return actively seeded/swarming transfers with full metadata by default — historical LocalIndex rows excluded unless Options → Shared Torrents Database → “Include inactive / historical shares” is enabled
  • new:Bitsearch added as a new REST-API torrent search engine (bitsearch.eu) — clean JSON, 200 free requests/day per IP, magnet links built client-side from DefaultTrackers. No crawling, replaces the gap left by the Idope removal
  • new:IP Filter now supports multiple block list formats — P2P, DAT, CIDR, and Hosts formats are auto-detected and parsed. ZIP archives are now supported alongside existing GZIP decompression. Extracted format readers into separate classes (P2PIPFilterInputStreamReader, DatFilterInputStreamReader, CidrFilterInputStreamReader, HostsFilterInputStreamReader) with shared IPFilterFormat enum
  • update:jlibtorrent to 2.0.12.9 with libtorrent RC_2_0 cb6fe6b9c (86 commits ahead of previous) — includes tracker URL validation hardening, SOCKS5 parsing fixes, resume-data sanitization, peer encryption improvements, symbolic link support (BEP 47), and 4 new Java APIs (natpmpGateway, allowMultipleConnectionsPerPid, natpmpLeaseDuration, pieceSizeForReq). OpenSSL upgraded to 3.6.0. Build now requires -frtti flag across all platforms due to upstream dynamic_cast in smart_ban.cpp
  • fix:Distributed search finds the IceBridge servers again — discovery probed DHT candidates one at a time and ran out of its 15 second budget on unreachable phones, so no peer was ever registered; probes now run in parallel, known and bootstrap servers go first, and dead endpoints back off so later passes reach the rest of the list
  • fix:The DHT bootstrap topic, where the dedicated IceBridge servers announce, is always queried first instead of only when the crowded relay and peer topics are empty
  • fix:Known IceBridge servers are retried even if they never answered before, a built-in seed server is always tried, and the Settings host ping verifies servers like discovery does instead of with a request they reject (which evicted healthy hosts)
  • fix:The IceBridge helper process no longer announces on the DHT with port 0, which republished our identity with a useless port and filled the shared topics with unreachable endpoints
  • fix:Results from peers that share their catalog are marked browsable again when a search returns more than a handful of results — the browsable flag was lost when larger result sets were streamed back in chunks, so only small answers showed the Browse Shared Torrents action
  • fix:Packaged desktop builds retain the IceBridge metrics used by the search transport, preventing distributed search startup from failing with a missing class; regression tests load the real application JAR without the daemon JAR
  • fix:Desktop IncomingSearchRequestHandler now receives LocalIndex so catalog browse works (parity with Android)
  • fix:Distributed search and relay responses follow live rUDP sessions after cellular NAT rebinding instead of stale registry endpoints
  • fix:Desktop clients now choose an automatic IceBridge UDP port instead of all using 6889 behind the same router; identity records and mesh registration advertise the actual bound port, supervised restarts retain it, and unknown peer ports are never guessed from our own port
  • fix:Distributed search now reaches peers that share content but do not relay (leaf/CLIENT nodes) — their published keyword fingerprint was being dropped by forwarders, so searches reached them only by fan-out luck and their torrents looked missing
  • fix:Distributed search and the relay stay responsive under heavy search traffic — rUDP packet processing is handed off the socket event loop, response delivery runs on a bounded lane, and concurrent torrent-metadata fetches are capped instead of exhausting threads
  • fix:IceBridge child supervision prevents orphan processes and preserves distributed search/TORRENT_FETCH across crashes and restarts
  • fix:Linux/Wayland startup no longer freezes or crashes when opening the Transfers tab — Java2D was forced onto the legacy software X11 pipeline, where on-screen icon and text blits are ~1000x slower; rendering now uses the XRender pipeline, which is fast and stable under XWayland
  • fix:JDK 26 HTTPS requests no longer fail after IceBridge identity initialization; Bouncy Castle is kept scoped to identity crypto instead of overriding the JVM-wide XDH provider
  • fix:macOS startup no longer crashes when the legacy libGURL JNI handler fails to load; magnet URLs use the Java Desktop OpenURIHandler included since Java 9, and obsolete libGURL code and binaries were removed
  • fix:Restored torrents stop landing at 0% — the session .torrent and its .resume sidecar now share one canonical hash (they used v1 vs v2), and restore heals installs written with the old mismatched names
  • fix:Born-complete torrents (per-file Share, auto-seed) now persist resume data at check completion and on every forced save — restarts no longer restore them under the default data dir at 0%
  • fix:Missing resume files are backfilled when a torrent is constructed, covering zero-piece torrents that never trigger a check
  • fix:Session .torrent files are ensured alongside resume data so magnet-origin torrents survive restarts instead of vanishing from restore
  • fix:SearchManager no longer cancels all global HTTP requests on stop — OkHttpClientWrapper.cancelAllRequests() was nuking non-search HTTP traffic (updates, FrostClick). Stopped performers now abort via the ‘stopped’ flag
  • fix:SearchMediator onResults IndexOutOfBoundsException — results.get(0) without null/empty check crashed the executor thread when a performer called onResults([])
  • fix:macOS installs ship icebridge.jar beside frostwire.jar and both jars’ native libraries are signed; frostwire.jar no longer duplicates daemon-only IceBridge classes
  • fix:Packaged JARs preserve dependency licenses without file/directory name collisions on case-insensitive filesystems, allowing macOS notarization to unpack embedded native libraries
  • fix:Idope search engine removed from commons, desktop, and android — idope.pics now requires TLS 1.3 and was failing handshakes on macOS arm64 and other TLS-1.2-only stacks. Removed IdopeSearchPattern, createIdopeTorrentSearch, SearchEngineID.IDOPE_ID, IDOPE_SEARCH_ENABLED, PREF_KEY_SEARCH_USE_IDOPE, all 39 localized use_idope strings, the android settings entry, and the desktop MCP engine registry. Added IdopeRemovalTest regression suite
  • fix:Standalone IceBridge forwarders launch with DHT and bootstrap discovery enabled, while release packages include icebridge.jar
  • fix:TORRENT_FETCH returns holder-signed full torrent metadata through EC2 relay hops, including piece layers for hybrid torrents
  • fix:The crawler sharing setting now gates both mesh browsing and DHT catalog publication; opting out withdraws the previous catalog, and only active non-private seeds are listed while ordinary distributed search still finds active downloads
  • fix:Only torrents you are actively seeding are shared with catalog crawlers — previously downloaded torrents that are not seeding are no longer published
  • fix:Crawler data stays anonymous — presence is stored as hashed endpoints and catalogs by publisher peer id only (never IP addresses)
  • fix:CRITICAL: matchedFile excluded from RemoteSearchResponse canonical bytes — Ed25519 signature did not cover the matched file path, allowing MITM tampering. Now included in appendRowBencode as “mf” key
  • fix:IP Filter critical blocking bug — add_rule() was passing flags=0 (allow) instead of ip_filter.access_flags.blocked.swigValue()=1, so blocked IP ranges were silently allowed through libtorrent (#1291) — caught by new IPFilterBlockingTest regression suite
  • fix:TLS hostname verification now uses proper suffix matching instead of substring contains — prevents attacker-controlled hostnames from matching whitelisted domains
  • fix:Timestamp-skew bypass via Math.abs(Long.MIN_VALUE) — Math.abs(Long.MIN_VALUE) returns a negative value, bypassing the >60s skew check in registration and response verification. Replaced with manual sign flip
  • fix:rUDP HELLO replay prevention — 8-byte Unix timestamp added to the signed message. HELLOs with timestamp skew > 300s are rejected (104-byte format only)
  • fix:IceBridge control API requires auth token (X-IceBridge-Token header) on all endpoints except /health — 32-byte random hex string generated at startup
  • fix:RegisterRequest canonical string uses length-prefixed fields to prevent delimiter injection
  • fix:RudpPacketCodec silent payload truncation — payloads >65535 bytes silently truncated the 2-byte length field, corrupting framing. Now rejected before encoding
  • fix:rUDP relay source verification — handleRelay verifies sourcePub matches the sender’s authenticated session identity
  • fix:rUDP hole-punch requires authenticated session — unauthenticated peers can no longer trigger amplification
  • fix:rUDP binds to 127.0.0.1 for local daemon profile — was 0.0.0.0, exposing unauthenticated handlers to the internet
  • fix:rUDP max sessions cap (256) — prevents memory exhaustion from unbounded session creation
  • fix:HTTP response body size capped at 16 MB (search) and 32 MB (torrent downloads) to prevent OOM from malicious or misconfigured servers
  • fix:SearchMediator search query sanitization — control characters stripped and query length capped at 1024 characters before dispatching to performers, preventing injection into URL templates, regex patterns, and JSON request bodies
  • fix:matchedFile length validation (max 4096 chars) in DistributedSearchPerformer and LocalSharedTorrentSearchPerformer — rejects pathologically long values from malicious remote peers
  • fix:DistributedSearchPerformer validates search result row fields — name max 2048 chars, infoHash must be 20 bytes, per-row try/catch prevents NPE from malformed responses
  • fix:IncomingSearchRequestHandler rate-limits per source to 30 requests/minute
  • fix:IncomingSearchRequestHandler rate-limits catalog browse by verified requesterPub after signature check (not transport sourcePub); search rate-limit owned by RelaySearchService
  • fix:FragmentReassembler DoS vulnerability — DATA_END with fragIndex=Integer.MAX_VALUE forced a 2-billion-iteration loop; assemble() had int overflow causing NegativeArraySizeException that killed the rUDP channel. Added MAX_FRAGMENTS_PER_GROUP (4096), MAX_ASSEMBLED_SIZE (16MB), and long accumulation
  • fix:IceBridge P0 hardening — cheap-reject-first ingress (rate-limit before Ed25519 verify), per-IP + global HELLO budgets, per-/24 session caps, empty HELLO_ACK removed; helloRejected/relayRateLimited/searchRateLimited/powRejected/spamMarkedDropped counters in /metrics
  • fix:IceBridge rejects unauthenticated rUDP application packets and applies backpressure instead of acknowledging messages that could not be delivered
  • fix:IceBridge mesh security — HELLO_ACK carries signed identity so initiators learn remotePub (fixes rejected multi-hop RELAY); RELAY_RESPONSE requires authenticated session (no fire-and-forget spoof); RELAY app payload capped to single rUDP fragment; hop TTL default 3; mesh fan-out 3; per-peer RELAY rate limit; local registry targets delivered via /poll without self-UDP
  • fix:Desktop release distributions no longer expose unauthenticated JMX or JDWP listeners
  • fix:IceBridge rUDP and relay TCP listeners now default to bind 0.0.0.0 (publicly reachable). Desktop bind host default changed from 127.0.0.1; IncomingRelayServer now supports explicit bind host (used by IceBridgeServer with config.host()).
  • new:Transfer Detail Files row context menu now offers Share for completed files, creating and seeding a torrent from that file (same behavior as the row’s share button)
  • new:Transfer Detail General tab offers Check Local Data and a per-torrent Sequential download toggle; Trackers menu offers Add Tracker with strong URL validation, and Edit Trackers now trims entries and names the offending line
  • new:Transfer Detail Check Local Data disables while the recheck runs and swaps in a progress bar with live phase and percent, then reports the outcome
  • new:Advanced BitTorrent settings now expose jlibtorrent 2.0.12.9 controls for NAT-PMP gateway override, NAT-PMP lease duration, and allowing multiple connections from the same peer ID
  • new:icebridge:// URL protocol handler — handles URLs of the form icebridge://<peer_pubkey_hex>/. Commands: /browse (fetch and display peer’s shared torrent catalog from DHT), /search/ (send a signed search request to a specific peer), /info (show peer details from PeerDirectory or DHT identity record). Integrated into the search bar — typing an icebridge:// URL triggers the handler instead of a normal search. Clipboard monitoring for icebridge:// URLs
  • new:About window shows the current Telluride build number
  • new:Transfers default columns — Actions, Name, Seeding, Size, Status, Progress, Down Speed, Downloaded, Uploaded, Up Speed, Time, Seeds; Tips/Donations hidden, Uploaded shown (existing custom layouts untouched)
  • new:Karma settings screen (Options > Karma) — displays own karma chain status (current epoch, available endorsement energy, total endorsements given, karma score) and a top-peers-by-karma leaderboard (top 20, with score, endorsement count, last-endorsed timestamp). Right-click to copy peer public keys
  • new:Peer directory settings screen (Options > Peers) — shows all known peers in a table with public key, hostname, uTP port, trust score, verified/spam status, endorser count, and last-updated time. Right-click to copy key, block (mark as spam), remove, or browse the peer’s shared torrents catalog (fetched via DHT BEP 46 using RemoteIndexFetcher)
  • new:Shared torrents database viewer (Options > Shared Torrents) — browse the local shared torrents index with search, showing name, size, file count, info hash, publisher key, timestamps, and matched file. Right-click to copy info hash, copy magnet link, or copy publisher key
  • new:IP Filter table right-click context menu with Edit and Remove actions — edit opens the Add Range dialog pre-populated with the selected range’s values, remove deletes the range and rebuilds the IP filter and BTEngine
  • new:IP Filter panel description now lists supported file formats (.p2p, .dat, .cidr, .hosts) and compression types (.gz, .zip)
  • new:Added MCP auto-configuration support for Grok Build in the shared AgentDetector / AgentConfigWriter (common module). Grok is now detected via grok binary in PATH + ~/.grok/config.toml presence. “Configure” writes a native TOML entry under [mcp_servers.frostwire] with url + enabled=true using the HTTP/Streamable transport. This allows direct MCP connection from Grok Build TUI to the local FrostWire MCP server (port 8796 by default).
  • update:Share dialog posts to X (x.com) with an X icon instead of the retired Twitter branding
  • cleanup:Local search is diagnostic only (default off) — same LocalIndex path as inbound IceBridge answers; peer discovery is Distributed Search
  • fix:IP Filter persistence restored (#1291) — jlibtorrent session state does not persist ip_filter across restarts, so custom ip_filter.db persistence is required
  • fix:IP Filter ip_filter.db corruption root cause (#1291) — atomic writes with synchronized access prevent concurrent corruption during import and clear operations
  • fix:IP Filter ip_filter.db hardened against corruption (#1291) — version-byte validation, break on bad entries, graceful recovery when loading a damaged database
  • fix:IP Filter options pane now visible on Java 26 (#1291) — made IPFilterPaneItem constructor package-private and added setAccessible(true) in OptionsPaneFactory to prevent IllegalAccessException when creating pane items via reflection
  • fix:IP Filter pane duplicate settings key crash (#1291) — made IPFilterTableMediator.getInstance() thread-safe (synchronized+volatile), guarded IPFilterPaneItem.initOptions() against mediator creation failures with ipFilterTable null check, and made OptionsPaneManager.show() cache panes before initOptions to prevent infinite re-creation loops
  • fix:IP Filter DataLine creation on Java 26 (#1291) — added setAccessible(true) in BasicDataLineModel.createDataLine() to allow reflection access to DataLine constructors across package boundaries
  • fix:IP Filter edit disappearance bug (#1291) — fixed off-by-one in BasicDataLineModel.refresh() causing edited rows to vanish from the table after an edit
  • fix:IP Filter robust db loading + Import button disabled when empty (#1291)
  • fix:IP Filter disabled tooltips on table to prevent macOS Input Method EDT freeze (#1291)
  • fix:IP Filter HTTP errors now shown in panel + blocklist site links added (#1291)
  • fix:IP Filter JNI calls moved off EDT to background threads to prevent UI stalls (#1291)
  • fix:IP Filter JPopupMenu background theming on dark themes (#1291)
  • fix:Hybrid torrents use their metadata v1 hash consistently in the shared index and transfer lookup; successful canonical indexing removes only metadata-proven truncated-v2 duplicates
  • fix:YouTube audio muxing and other HTTP post-processing finish before automatic torrent creation or sharing, so the seeded torrent describes the final file; cancellation and failed-mux fallback are covered by completion-order regressions
  • fix:ThreadPool stack size increased from 4 KB to 512 KB — the previous 4 KB stack was far below the JVM default and caused StackOverflowError on deep call chains
  • fix:Sharing a file that no longer exists on disk is refused with a clear error instead of creating a torrent that can never complete
  • fix:VPN detection false positive on macOS — system utun interfaces (iCloud, Back to My Mac) were falsely detected as active VPN tunnels even when VPN was off, because they match the “utun” interface name pattern. Now validates that utun interfaces have a real routable IPv4 address before counting them as VPN. Also added “vpn” to interface name checks for broader VPN detection coverage
  • fix:HTTP search responses now check for 4xx/5xx error codes before returning the body — Cloudflare challenge pages and rate-limit responses are no longer passed to parsers as if they were valid search results
  • fix:DHT peer discovery ConcurrentModificationException — snapshot TcpEndpoint lists from dhtGetPeers before iterating (jlibtorrent alert threads can mutate live lists)
  • fix:MCP streamable HTTP handshake for Grok + other agents: notifications/initialized now returns 202 Accepted + “accepted” body (text/plain) + data: accepted on SSE stream. No initial data on GET SSE open. Allows grok mcp doctor frostwire (and rmcp-based clients) to complete connect instead of hanging on “Sse(session)”.
  • fix:YouTube downloads preserve headers, ranges, cancellation, and resume behavior; Telluride build 47 uses yt-dlp 2026.8.19
  • fix:YouTube search returns both best video and best audio streams, including muxed-only responses
  • fix:Newly created YouTube/HTTP torrents are indexed immediately after auto-seeding
  • fix:Search result table Seeds and Size columns now sort numerically — clicking Seeds ranks 436 above 64; previously sorted lexicographically as strings or by relevance score instead of seed count
  • fix:Default tracker list in TorrentUtil, CreateTorrentDialog, and UrlUtils updated to 16 trackers that responded to a BEP 15 connect_request probe on 2026-06-08 — removed 6 dead trackers (opentrackr, openbittorrent, exodus, moeking, explodie, coppersurfer) and added reliable replacements from ngosang/trackerslist per #1004. New DefaultTrackerListTest regression suite asserts all three files stay in sync
  • fix:SoundCloud default credentials refreshed to the values published at update.frostwire.com/android (client_id=A8wpv6WPWhcpz9BhiL66KfK8IHy6NLoz, app_version=1780910323) — pre-existing drift across SoundCloudConfigFetcher, SoundcloudSearchPattern, SoundcloudUtils, and SoftwareUpdater fallbacks now also aligned
  • fix:shared_files_fts switched from external content FTS5 table (with triggers) to standalone FTS5 table with manual index management — external content “delete” triggers failed silently when rowids were reused, causing stale FTS entries
  • fix:INSERT OR REPLACE on shared_torrents orphaned shared_files rows — REPLACE assigns a new rowid, leaving old file rows unreferenced. Now pre-deletes old shared_files rows before the replace
  • fix:sanitizeFtsQuery now replaces non-alphanumeric separators (underscore, dot, dash, slash) with spaces instead of dropping them — prevents mismatch between FTS5 tokenizer (which splits on these chars) and the query sanitizer (which was concatenating tokens like “real_file” into “realfile”)
  • fix:Knaben search query JSON now properly escaped via Gson
  • fix:Metadata-less magnets are replaced by the real libtorrent transfer, preserving x.pe peers and avoiding invalid piece-layer reconstruction
  • fix:Mesh magnets no longer advertise BitTorrent port 0 from failed listeners
  • fix:Stop seeding PeerDirectory with unverified IceBridge host-cache placeholders (reduces self/auth spam); host cache remains UI/history only
  • fix:Distributed search multi-hop disabled (ttl=0) — re-signing forwarded requests with the forwarder key while keeping original requesterPub always failed verification; v1 is direct verified-peer search only until dual-envelope hop protocol
  • fix:RudpSession sequence-wrap deadlock — after ~2^31 packets, signed comparison treated the wrapped sequence as a duplicate, permanently stalling the session. Fixed with Integer.compareUnsigned for all sequence comparisons and ConcurrentSkipListMap comparator
  • fix:RudpSessionManager pending-packet memory leak — unacked reliable packets were never purged after timeout; only cleared by ackLocal(). Now removed after MAX_RETRIES or RETRANSMIT_TIMEOUT_MS
  • fix:IceBridgeServer peerTtlSec*1000 overflow — for large config values, long multiply overflowed to negative, disabling eviction. Fixed with Math.multiplyExact
  • fix:PeerRegistry capacity enforcement — the maxPeers limit was checked AFTER merge(), so byPubHex.containsKey(key) was always true for a just-added peer; new peers were never rejected. Now checked BEFORE merge
  • fix:FragmentReassembler cross-session collision — group key changed from int groupId to String (sender + groupId)
  • fix:TORRENT_FETCH serves torrents up to 256KB (was 64KB) with signed TOO_LARGE above; holder-signed chunks are cached and restamped per request nonce (metadata protocol v2)
  • fix:IdentityRecord.fromEntry accepts v1/v2 again (read path) — still writes v3 with caps; fixes self-ping / peer handshake decode after capability bump
  • fix:SearchManager checkIfFinished race — crawl() and submitSimpleSearchTask() now add tasks inside synchronized(tasks) blocks, closing the race where a CrawlTask was enqueued between checkIfFinished’s ‘no pending’ check and the onStopped callback
  • fix:SearchResultDisplayer entries list now synchronized — the static ArrayList was mutated from EDT and iterated from search executor threads without synchronization, risking ConcurrentModificationException. Now a Collections.synchronizedList with synchronized blocks on all iteration paths
  • fix:AbstractSearchPerformer thread-safety — ‘stopped’ and ‘listener’ fields were not volatile; stop() from EDT was not visible to executor threads, causing results to be delivered after user clicked Stop
  • fix:DistributedSearchPerformer pending-map leak and NPE — timed-out searches leaked PendingRequest entries; malformed response rows with null infoHash caused NPE before latch countdown. Pending cleared in finally; rows validated
  • fix:SearchEngine TPB _domainName not volatile — background thread wrote _domainName; isReady() read it on EDT. Without volatile, TPB might never become ready. Also added try/catch and named daemon thread for mirror fetch
  • fix:Newly indexed torrents trigger a coalesced routing-digest refresh instead of waiting for the periodic rebuild; writes during an announcement schedule a follow-up and removing the last row withdraws previous holdership
  • fix:macOS native icon preloading reuses the existing Aqua file view instead of constructing a new file chooser for every file extension, avoiding repeated multi-second stalls on the Swing event thread
  • fix:Library media-type rescans are coalesced, so a burst of completed downloads no longer overflows the background executor and spams RejectedExecutionException
  • fix:right-clicking the transfer detail Files tab with no row selected no longer throws a NullPointerException
  • fix:Desktop UI repaints only rows that actually changed instead of every table row each second, theme icons decode once instead of on every paint, and Tip of the Day renders without subpixel-text stalls
  • fix:SearchMediator onResults no longer blocks search executor threads on the EDT — changed safeInvokeAndWait to safeInvokeLater so results are dispatched asynchronously
  • fix:JdkHttpClient.head reads response code before disconnect and drains error stream to prevent socket leaks
  • fix:IdentityKeys.generate() now uses jlibtorrent’s native Ed25519 for keypair generation instead of the JDK’s KeyPairGenerator — the JDK’s pure-Java Ed25519 implementation is 50-100x slower than native on some platforms (macOS arm64), causing first-run identity PoW mining to take >2 minutes instead of ~1-2 seconds
  • fix:InboundMessageQueue O(n²) performance — ConcurrentLinkedQueue.size() (O(n)) was called in a while-loop for overflow eviction. Replaced with AtomicInteger counter
  • fix:SearchMediator filter token-mutation fragility — searchTokens list was passed to filter2 which could mutate it via internal token removal. Now a defensive copy is made at the filter entry point
  • fix:SearchEngine.getSearchEngineByName prefix matching — fragile name.startsWith() replaced with exact name match or name + space prefix to prevent short engine names from matching longer ones
  • fix:SearchEngine TPB mirror fetch error handling — added try/catch and named daemon thread instead of raw new Thread()
  • fix:IceBridgeProcessLauncher temp log directory leak — every start/stop cycle leaked a temp directory with log files. Now recursively deleted in close()
  • fix:IceBridgeServer.parseArgs now skips –auth-token (handled separately by parseAuthToken) — previously threw IllegalArgumentException on unknown option
  • fix:Torrent crawl cache replaced with LRU eviction (LinkedHashMap, max 500 entries) — old cache had no eviction, causing unbounded memory growth in long-running sessions
  • fix:CrawlPagedWebSearchPerformer cache no longer uses global synchronized lock — the underlying DatabaseCrawlCache handles its own thread safety. Cache field is now volatile with local-variable snapshots
  • fix:parseFilesJson capped at MAX_FILES_PER_TORRENT (10000) — prevents unbounded row growth for torrents with tens of thousands of files
  • fix:SearchEngine.getEngines cached as static final — was allocating a new Arrays.asList on every call (per search, per result lookup, per engine lookup)
  • fix:SearchManager removed O(n²) nextOrdinal — the method iterated all tasks per crawlable result and was never used for sorting (no priority queue). Removed Comparable, ordinal field, and nextOrdinal method
  • fix:SearchMediator stripHtml regex precompiled — two String.replaceAll calls per result were recompiling regex on every search result. Now static final Pattern
  • fix:CrawlPagedWebSearchPerformer crawl counter is now AtomicInteger
  • fix:PerformersHelper.reduceHtml no longer double-allocates strings
  • fix:PerformersHelper relevance-ranking hot path — eliminate per-result regex compilation in sanitize/normalize (www. stripping and combining-mark removal after NFKD), speeding up fuzzy matching and result normalization on large search result sets
  • fix:CompositeFileSearchResult Builder no longer allocates 5 Optional wrappers per build() — nullable fields with Optional created at accessor boundary only
  • fix:Regex search patterns (Nyaa, Torrentz2) are now compiled once as static final fields
  • fix:Removed Sec-Fetch-Mode: navigate header from all HTTP requests
  • fix:NullTrustManager certificate list is now thread-safe (CopyOnWriteArrayList)
  • fix:Mesh log volume — per-packet/per-rejection logs demoted to DEBUG (metrics counters carry the signal); systemd unit caps journal spam (LogRateLimit 2000/30s)
  • fix:Transfer Detail Files tab keeps the selected file row highlighted while the view refreshes every second, and skips the rebuild entirely when the visible rows are unchanged
  • fix:transfer action buttons no longer flicker between enabled and disabled while a download is in progress; share/play availability is computed per row off the EDT instead of being cached on the single shared renderer
  • fix:Transfer Detail Files tab no longer freezes per-file progress while a transfer is still moving — holders rebuild on torrent progress drift, settled torrents skip native calls
  • fix:Slideshow / MISC HTTP no longer dies on OkHttp HTTP/2 stream header timeout (o2.php) — MISC client is HTTP/1.1, shared clients send HTTP/2 pings, slideshow retries once after evicting a stale pool
  • fix:macOS file rows show rich native icons again — the JFileChooser native view is used (FileSystemView returns only generic icons on JDK 26) and the bundled app passes –add-exports for com.apple.laf like frostwire.sh does
  • fix:Transfer detail Pieces tab now uses jlibtorrent’s v2-aware pieceSizeForReq() API for accurate piece-size display
  • new:rUDP (Reliable UDP) transport implemented from scratch — Ed25519-authenticated HELLO handshake, sequence-numbered DATA with ACK and retransmission (500ms interval, 5 retries, 5s timeout), application-level fragmentation/reassembly for payloads exceeding the UDP MTU (DATA_FRAG + DATA_END packet types, 1024-byte chunks with 12-byte fragment headers), HOLE_PUNCH for NAT traversal, and RELAY forwarding through forwarder peers. Built on Netty NioDatagramChannel
  • new:IceBridge control API — localhost-only HTTP server with endpoints: /health, /register (Ed25519-signed peer registration), /route (localhost-trusted unsigned peer routing), /lookup, /send (opaque payload delivery), /poll (drain inbound messages), /metrics
  • new:IceBridge multi-hop mesh RELAY — hop TTL frame, Type.RELAY delivery, forwarder mesh via RelayMesh; MultiRelayMeshSearchTest (3 FORWARDER + seeder/searcher clients)
  • new:IceBridge multi-protocol fabric — all mesh payloads IBP1-framed with protocolId on /send and /poll (SEARCH=1)
  • new:Node capability advertisement — IdentityRecord v3 caps bitflags (RELAY/SEARCH/INDEX/STORE/DHT/TORRENT/AI); PeerDirectory filters by capability; roles still derived for DHT topics
  • new:Streaming distributed search responses — RESULT chunks with final flag; large result sets stream multiple signed frames; performer accumulates until final
  • new:Distributed search forwarding (v2) — search requests now use ttl=1 and include the requester’s pubkey in the path array, enabling one-hop forwarding through trusted peers. IncomingSearchRequestHandler forwards requests to up to 3 trusted peers not already in the path, re-signing each forwarded request. Anti-amplification: max 3 forward targets, existing rate limits apply
  • new:Standalone IceBridge embedded DHT announce — pure FORWARDER nodes publish on frostwire-relays-v1 (+ optional bootstrap) via minimal jlibtorrent SessionManager without FrostWire desktop; ICEBRIDGE_DHT / –dht / –no-dht; DhtAdvertiser accepts SessionManager supplier
  • new:Remote peer catalog fetch protocol — RemoteIndexFetcher fetches a peer’s shared torrent catalog from the DHT via BEP 46 (IndexAnnouncementPublisher manifest). RemoteCatalogBrowseRequest provides a signed request/response protocol for browsing a specific peer’s catalog over the IceBridge transport. IncomingSearchRequestHandler handles both search requests and catalog browse requests
  • new:IndexAnnouncementPublisher wired into DhtAdvertiser — shared torrent index manifests are now published to the DHT every 5 minutes alongside identity records, enabling peers to discover each other’s shared catalogs
  • new:IceBridge topology limits — IceBridgeTopology + env ICEBRIDGE_MESH_FANOUT / SEARCH_PEER_FANOUT / MESH_HOP_TTL / SEARCH_TTL / SOFT_MAX (remote-config ready)
  • new:Headless IceBridge presence crawler and mirror tooling (DHT heartbeat-topic presence counts, catalog crawler, allowlist-driven re-sharing)
  • new:Pipeline saturation is observable — /metrics reports poll runs/errors, drain volume, request-queue depth, rejected work, and verification failures
  • new:IceBridge rUDP bind host configurable (ICEBRIDGE_BIND_HOST setting) — use “0.0.0.0” to accept rUDP from remote peers (cloud forwarder mode) or “127.0.0.1” for local-only daemon mode (default). Control HTTP server always binds to localhost
  • new:IceBridge software version announce — IdentityRecord v4 ib_ver + control /register+/lookup; Peers table IceBridge column; constants SOFTWARE_VERSION=1.1.0 / SOFTWARE_VERSION_CODE=1 for future crawler penetration stats
  • new:Dual-envelope distributed search multi-hop (v2) — requester signature covers query only; hops preserve sig; default ttl=2; PeerRegistrySync registers self and imports IceBridge mesh peers (forwarder-first discovery)
  • cleanup:Removed the legacy doctor-servlet bug report dialogs; errors report silently through Icebase, deadlocks through the crash spooler, and the fatal dialog no longer contacts the retired endpoint
  • fix:common/ relay identity and IceBridge file I/O no longer use java.nio.file (Android-safe File streams)
  • new:IdentityKeys.fromSeed() — deterministically reconstructs an Ed25519 keypair from a 32-byte seed via jlibtorrent’s Ed25519.createKeypair, enabling identity restore from a BIP39 mnemonic. X25519 keypair is freshly generated (not derivable from the Ed25519 seed). IdentityKeys.save/load are now public for import/export
  • new:DistributedSearchTransport abstraction — transport-agnostic listener-based interface that decouples the search performer from the concrete transport (IceBridge or future alternatives). A single background poller feeds all listeners, preventing races between the performer and incoming-request handler
  • new:IceBridgeClient and IceBridgeProcessLauncher — desktop HTTP client for the local IceBridge daemon, plus subprocess launcher that starts icebridge.jar with auto-allocated ports, shared identity, and redirected log output
  • new:IncomingSearchRequestHandler — permanent listener that processes incoming search requests through RelaySearchService and sends signed responses back via the transport
  • new:PeerRegistrySync — periodic daemon thread that syncs verified PeerDirectory entries into the IceBridge daemon’s registry via /route every 30 seconds, using the well-known rUDP port 6889
  • new:KeyspaceRouter ranks peers by XOR distance of SHA-1(keywords) for future responsibility-based routing (search still fans out trust-ordered peers first)
  • refactor:DistributedSearchPerformer refactored from direct-TCP OutgoingRelayClient to transport-agnostic DistributedSearchTransport — the performer now sends requests via transport.send() and collects responses through a temporary PayloadListener registered for the duration of the search. Removed thread pool; the transport’s poller handles delivery
  • refactor:OutgoingRelayClient verification extracted into shared SearchResponseVerifier (DRY) — both the direct-TCP and IceBridge paths now apply identical nonce, timestamp-skew, and Ed25519 signature checks
  • refactor:IceBridge client classes (IceBridgeClient, IceBridgeSearchTransport, IncomingSearchRequestHandler, PeerRegistrySync) moved from desktop to common for Android reuse. IceBridgeClient rewritten with OkHttp (replaces java.net.http.HttpClient). IceBridgeServer auth token stdout leak removed
  • refactor:PeerDiscoveryScheduler, DhtAdvertiser, KarmaChainWriter, KarmaChainPublisher, KarmaChainCommitScheduler moved from desktop to common for Android reuse. KarmaChainStore interface extracted — KarmaChainTable now implements it. KarmaChainWriter depends on the interface instead of the concrete table
  • new:Multi-instance distributed search test — headless integration test that simulates two FrostWire instances on the same machine with different identities, ports, and local indexes, verifying cross-instance search via real rUDP
  • new:LocalIndex.listAll() — enumerate all shared torrents in the local index for UI browsing
  • new:DistributedSearchEngineWire.getPeerDirectory() — static accessor for the shared PeerDirectory instance, enabling UI panels to access peer data
  • new:IceBridge hybrid EC2 topology benchmark + TopologyAutoResearch auto-loop optimizes N/M/TTLs for hit-rate vs traffic on fat EC2 hub mesh + FrostWire leaves; hybrid profile N=16 M=30; LimeWire ultrapeer baseline retained
  • new:Standalone IceBridge (icebridge-run-local.sh / AWS) logs successful mesh traffic at INFO — HELLO, HELLO_ACK, RELAY, SEARCH, TELEMETRY/PING and other known protocolIds
  • fix:PeerRegistrySync rUDP port is now configurable via constructor parameter
  • fix:Removed dead estimateRowsBytes() method from RemoteSearchResponse
  • fix:SCHEMA_VERSION bumped to 2 to reflect shared_files and shared_files_fts table additions
  • refactor:Tracker list consolidated into a single source of truth at com.frostwire.bittorrent.DefaultTrackers (#1004) — TorrentUtil, CreateTorrentDialog, and TorrentsCSVSearchPattern now consume DefaultTrackers.ANNOUNCE_URLS / MAGNET_URL_PARAMETERS. Removed duplicated UrlUtils.USUAL_TORRENT_TRACKERS_MAGNET_URL_PARAMETERS
  • cleanup:Desktop builds support JDK 26 by upgrading google-java-format from 1.24.0 to 1.36.1
  • fix:IceBridge ops scripts — run-local kills previous instances and detaches safely on Ctrl+C; systemd install is one-step (builds the jar, sudo self-elevation with JAVA_HOME passthrough, stops port strays, no crash-loops)
  • cleanup:GPL header on all post-2020 Java files missing it (79 files)
  • cleanup:Identity settings UI uses shared IdentityLifecycle (common/) for generate/install/seed/import/export — same logic as Android
  • new:ICEBRIDGE_ARCHITECTURE_REVIEW.md north-star layering + implementation status matrix
  • cleanup:Drop pre-alpha wire shims — no bare SEARCH payloads, no dual response signature domain, no IdentityRecord v1/v2 parse, no 96-byte HELLO auth
  • fix:IceBridge CLI prints identity load vs proof-of-work mining progress on stdout (first-run no longer looks hung); non-protocol TCP 6888 probes at DEBUG without stack spam
  • fix:IceBridge ops scripts — systemd install creates writable /opt dir; control URL is SSH tunnel only (127.0.0.1 bind); install uses absolute java path and preserves icebridge.env; no –background+–gradle; default control HTTP 8081 aligns run-local/fromEnv/.env.example
  • new:IceBridge fat JAR multi-arch jlibtorrent natives (Linux x86_64/arm64 + macOS) so Mac-built icebridge.jar runs DHT on EC2; scripts/icebridge-systemd-install.sh
  • new:ICEBRIDGE.md operator stub (ports, local vs remote, tokens, co-located pitfalls, security model)

New FrostWire for Android 3.2.1 build 777

Distributed Search just got a lot better at finding things, and a lot more reliable at starting up.

What’s new

⬇️ frostwire-release-3.2.1-build-777.apk

Browse what other people share. Long-press a Distributed Search result and choose Browse Shared Torrents to see everything that person is sharing, then download straight from them. The first-run wizard now explains that seeding a torrent makes it discoverable. Browsing is on by default for torrents you are actively seeding (never your download history); you can turn it off in the wizard or in Settings > Distributed Search.

Smarter, faster search. Peers now tell the network what kind of content they hold, so your search goes to the people most likely to have it instead of random ones. Rare files turn up more reliably, even from phones and computers that are not acting as relays. Unreachable peers are forgotten instead of being retried forever, and Distributed Search is ready sooner after you open the app.

Clearer IceBridge status. Settings > Distributed Search now tells you what is actually happening: which startup step it is on, what went wrong if it failed, and a live countdown before the next automatic retry. It never gets stuck on “Starting…” without a reason.

Fixes you may notice

  • Distributed Search starts on release builds. A code-shrinking bug could stop the IceBridge networking layer from starting at all on installed apps. That is fixed, and the build now checks for it.
  • Downloads from the Peer catalog use the exact peer you picked, and failed or rejected starts (including VPN restrictions) are shown instead of silently disappearing.
  • Several phones on the same Wi-Fi no longer fight over one network port.
  • Transfers update right away when a torrent moves from Checking to Seeding, and when you come back from the details screen.
  • Only real audio files open in the music player; videos open with your system chooser.
  • Search results with accented or non-Latin names no longer go missing or appear twice.
  • The background service stops cleanly instead of crashing, and VPN or Wi-Fi-only rules no longer override a torrent you paused yourself.

Powered by jlibtorrent 2.0.12.9.

Full changelog

  • new:You can now browse the torrents a peer shares — long-press a Distributed search result whose holder allows crawling (“Browse Shared Torrents”) to list everything that peer is sharing and download any of it straight from that peer
  • new:Distributed search routes to the peers that actually hold the content — nodes announce a compact keyword fingerprint and requests are forwarded to likely holders with a small bounded fan-out instead of random peers, so rare results are found reliably and faster
  • fix:Distributed search now finds torrents shared by peers that do not act as relays (leaf nodes) — forwarders were dropping their published keyword fingerprint, so those torrents only showed up by luck; the fingerprint is now honored when routing
  • fix:Release builds retain Netty’s dynamically accessed Android memory-fence fallback, preventing IceBridge startup from failing after code shrinking; release DEX verification gates packaging
  • fix:IceBridge settings show actual startup phases, timeout and failure status, and a live retry countdown; startup attempts are coalesced, late attempts cannot publish, and failed starts retry at most three times without bypassing cleanup or network policy
  • new:Seeding is publishing — the first-run wizard explains that seeding a torrent makes it discoverable on the BitTorrent network, and lets you opt out (on by default) of having the torrents you are actively seeding browsable by the network’s crawlers
  • fix:The crawler sharing setting now gates both mesh browsing and DHT catalog publication; only active non-private seeds are browsable, and opting out withdraws the previous catalog without disabling ordinary distributed search
  • fix:Only torrents you are actively seeding are shared with catalog crawlers — downloaded history that is not seeding is no longer published
  • fix:Distributed search becomes available sooner after startup — peer discovery, signed DHT announcements, and mesh registration now begin immediately in parallel rather than blocking the search UI; resume recovery uses one timeout budget
  • fix:Distributed search and the relay stay responsive under heavy search traffic — packet processing is handed off the socket event loop, response delivery runs on a bounded lane, and concurrent torrent-metadata fetches are capped
  • new:Peers keep an up-to-date list of reachable IceBridge nodes and never query unreachable ones — nodes that stop answering (directly or through a relay) are removed from the local list and evicted instead of being retried forever
  • fix:IceBridge UDP ports now default to automatic selection so multiple devices behind one router do not all claim port 6889; existing default settings are upgraded once, custom ports remain supported, and announcements use the actual bound port
  • fix:Peer catalog downloads preserve the selected holder’s identity, show rejected starts and VPN restrictions, and keep failed metadata transfers visible as errors instead of silently removing them
  • new:IceBridge participates as a full node (BOTH) by default, with a separate relay-participation switch and a node setting that restarts the relay stack when changed
  • new:Search progress now shows IceBridge status — “Distributed Search · N peers contacted” with starting / not-running hints, translated to every supported language
  • fix:Warming the mesh on relay startup lets a fresh install find peers without waiting for the first discovery tick
  • fix:Shared hybrid torrent indexing consistently uses the metadata v1 hash and removes only proven truncated-v2 aliases after the canonical row is stored
  • fix:The local search index preserves FTS rowids across reindexing and repairs triggers, fixing missing or duplicated results with unicode names
  • fix:VPN and seeding preference toggles suspend torrents for policy without overwriting an explicit user pause, and the transfer list is no longer cleared on reset
  • fix:The engine’s foreground service stops cleanly when promotion fails instead of crashing with RemoteServiceException
  • fix:Network status changes are no longer rebroadcast, and notifications fire only for real Wi-Fi/mobile/VPN transport changes
  • fix:Transfers rows now react to libtorrent state-change alerts, so Checking-to-Seeding updates do not wait for the next periodic list refresh
  • fix:Returning from transfer details immediately refreshes the transfers list so the row reflects the latest Checking, Downloading, or Seeding state
  • fix:Only real audio files open in the music player; video containers (webm/mp4/mkv/…) open with the system chooser
  • fix:Distributed Search settings refresh automatically while the screen is visible
  • fix:Deselecting every web search engine leaves Distributed Search enabled and no longer re-enables Archive.org at startup
  • fix:Release shrinking ignores optional Netty codec, JFR, and LDAP classes that Android does not ship, so the release build can complete

jlibtorrent 2.0.12.9 is out — 86 upstream fixes, v2 torrent precision, and sharper NAT traversal

By the FrostWire team — github.com/frostwire/frostwire-jlibtorrent

We’re happy to ship jlibtorrent 2.0.12.9, the latest Java/JNI bindings for the libtorrent RC_2_0 branch. This release advances the underlying C++ engine by 86 commits (from 46cc651d to cb6fe6b9c), pulls in OpenSSL 3.6.0, and exposes four new Java APIs that give you finer control over NAT-PMP traversal, peer connection policies, and BitTorrent v2 metadata.

If you build BitTorrent clients, media streaming tools, or decentralized data pipelines in Java, this is the build you want.

What’s inside

1. TorrentInfo.pieceSizeForReq() — v2-aware piece sizing

BitTorrent v2 (hybrid and v2-only torrents) introduced Merkle trees and pad blocks to align pieces with 16 KiB blocks. That means the nominal piece size you read from a .torrent file and the actual number of bytes you must hash or request can differ.

pieceSizeForReq(int piece) returns the effective piece size for hash requests — the real byte count you pass to a hasher or a piece picker. For v1 and hybrid torrents it equals pieceSize(); for v2-only torrents it strips out padding so your progress bars and verification loops stay exact.

TorrentInfo ti = new TorrentInfo(torrentBytes);
long totalDataBytes = 0;

for (int i = 0; i < ti.numPieces(); i++) {
int reqSize = ti.pieceSizeForReq(i);
totalDataBytes += reqSize;
// allocate exactly reqSize bytes for the piece buffer
}

// totalDataBytes == ti.totalSize() for v1/hybrid
// totalDataBytes <= ti.totalSize() for v2 (pad blocks excluded)

Use it when:

  • Computing precise download progress on v2 torrents
  • Allocating per-piece hash buffers in a cross-version client
  • Building telemetry that must reconcile “bytes on disk” vs “bytes of content”

2. SettingsPack.natpmpGateway() — override the NAT-PMP gateway

NAT-PMP auto-discovery fails on VPNs, container networks, and multi-homed hosts. natpmpGateway(String) lets you point libtorrent at the exact gateway address to punch through.

SettingsPack pack = new SettingsPack();
pack.natpmpGateway("10.200.1.1"); // WireGuard exit node
session.applySettings(pack);

Leave it empty ("") and libtorrent falls back to automatic detection — the old behavior.

3. SettingsPack.allowMultipleConnectionsPerPid() — relax the duplicate-peer guard

By default libtorrent drops connections that share the same peer ID, a simple loop-prevention rule. In carrier-grade NAT (CGNAT) environments, dozens of legitimate peers can share one public IP and one peer ID. Enabling this setting lets you keep talking to all of them.

SettingsPack pack = new SettingsPack();

// Only enable on private trackers or known-CGNAT swarms
if (trackerIsCGNATHeavy(announceUrl)) {
pack.allowMultipleConnectionsPerPid(true)
.connectionsLimit(500); // raise ceiling to match
}

Security note: don’t flip this on open public swarms — it opens a trivial amplification vector.

4. SettingsPack.natpmpLeaseDuration() — control mapping lifetime

NAT-PMP mappings expire. The default lease is 3600 seconds (1 hour). For short mobile sessions you may want 300 s; for seed boxes, 7200 s reduces background chatter.

SettingsPack pack = new SettingsPack();

switch (deviceProfile) {
case MOBILE_TEMPORARY -> pack.natpmpLeaseDuration(300);
case DESKTOP_STANDARD -> pack.natpmpLeaseDuration(3600); // default
case SEED_BOX -> pack.natpmpLeaseDuration(7200);
}

Libtorrent auto-renews at roughly 50 % elapsed time, so a 300 s lease triggers a refresh every ~150 s.


Build & dependency updates

DependencyBeforeAfter
libtorrent46cc651dcb6fe6b9c (86 commits)
OpenSSL3.5.23.6.0
Boost1.88.01.88.0 (1.91.0 tested, ABI issue on macOS arm64)
SWIG4.3.14.4.1

The upstream 86-commit delta includes hardening around tracker URL validation, SOCKS5 parsing, resume-data sanitization, peer encryption, and symbolic link support (BEP 47). Your users get those fixes for free the moment they load the new native library.

Build note: -frtti is now required

One upstream commit (d0e59960a) introduced dynamic_cast inside the smart-ban plugin. That collides with our traditional -fno-rtti builds. We added -frtti to all platform configs (macosx-arm64, linux-arm64, and by extension the Docker-based Linux/Windows/Android builds on our EC2 farm). Binary size impact is negligible; correctness is non-negotiable.


Get it

Maven (GitHub Packages)

repositories {
maven { url "https://maven.pkg.github.com/frostwire/frostwire-jlibtorrent" }
}

dependencies {
def v = '2.0.12.9'
implementation "com.frostwire:jlibtorrent:$v"
implementation "com.frostwire:jlibtorrent-macosx-arm64:$v" // or your platform
}

Direct download

JARs are attached to the GitHub Release. Grab the platform-independent jlibtorrent-2.0.12.9.jar plus your native artifact:


Full upstream changelog (libtorrent 46cc651d → cb6fe6b9c)

Notable upstream commits consumers should care about:

  • Sanitize resume data — reject mismatching info-hashes in resume data (read_resume_data now logs a warning)
  • Strengthen peer encryption — obfuscation layer tightened
  • SOCKS5 hardening — edge cases in UDP unwrap, CONNECT Host header parsing, and redirect handling patched
  • Tracker URL validation — stricter parsing to prevent malformed announce URLs from crashing the tracker manager
  • BEP 47 symlink support — create_torrent now stores symbolic links correctly in v1/v2 metadata
  • NATPMP gateway override — the libtorrent feature that became our natpmpGateway setting
  • Multiple connections per peer ID — the libtorrent feature that became our allowMultipleConnectionsPerPid setting
  • NAT-PMP lease duration control — the libtorrent feature that became our natpmpLeaseDuration setting
  • Add high_priority reannounce flag — carried forward from 2.0.12.8
  • Add disk_disable_copy_on_write — carried forward from 2.0.12.8
  • Add file pool performance counters — carried forward from 2.0.12.8

Compatibility

  • Java source/target: 17
  • BitTorrent protocols: v1, v2, hybrid (v1+v2)
  • Platforms: macOS (arm64, x86_64), Linux (x86_64, arm64), Windows (x86_64), Android (arm, arm64, x86, x86_64)

New frostwire-android-3.1.4-build-775

  • frostwire-android-release-3.1.4-b775-plus.apk

    fix:Music player notification now opens a fresh AudioPlayerActivity via a no-UI trampoline that builds MainActivity under the player; MediaSession/session content intents point to the trampoline, and MainActivity forwards Android/Oplus Seedling media-launch intents to the player for compact System UI media cards
  • fix:Transfer Detail no longer crashes with ClassCastException when a torrent is still in fetch phase; AbstractTransferDetailFragment.ensureTorrentHandle now guards getBittorrentDownload() results with instanceof before casting, preventing TorrentFetcherDownload→UIBittorrentDownload cast failures
  • fix:My Music song deletion now removes items from the list adapter immediately instead of waiting for the background MediaStore deletion and loader refresh; DeleteDialog fires a pre-delete callback that optimistically removes deleted IDs from ApolloFragmentAdapter before file deletion begins
  • fix:SoftwareUpdaterDialog and NewTransferDialog no longer crash on Android 12 and lower with NoSuchMethodError; removed androidx BundleCompat.getSerializable() which internally calls the API 33-only typed overload, now using legacy Bundle.getSerializable(String) with explicit cast
  • fix:RenamePlaylist no longer crashes from background-thread getActivity() NPE when the dialog fragment detaches before MISC handler queries the playlist name; initObjects now passes application context and UI callbacks guard isAdded()/getDialog() null
  • fix:ArtistAlbumFragment onItemClick no longer crashes with NPE or races when calling getActivity().finish() from the MISC handler; activity is captured locally before the async post and finish() is marshalled back to the UI thread with lifecycle guards

FrostWire 7.0.4 — MCP Server, No More Freezes, and a Faster UI

We’re excited to announce FrostWire 7.0.4 for desktop — a release packed with a brand-new built-in MCP server, comprehensive EDT freeze fixes that eliminate UI hangs across the app, major rendering improvements to the transfer Pieces panel, and several quality-of-life features for torrent creation and management.

Windows Installer: frostwire-7.0.4.windows.exe

MacOS Installers:
frostwire-7.0.4-x86_64.pkg (Intel)
frostwire-7.0.4-arm64.pkg (Apple Silicone)

Linux
frostwire-7.0.4.x86_64.tar.gz (Intel)
frostwire-7.0.4.arm64.tar.gz (Arm64)

What’s New

Built-in MCP Server

FROSTWIRE_SKILL.md

FrostWire now ships with a built-in Model Context Protocol (MCP) server — a first for any BitTorrent client. This opens up FrostWire to the AI tooling ecosystem with 38 desktop tools across 8 categories, settings-pane controls, and client configuration support for:

  • GitHub Copilot
  • Codex
  • Claude Desktop
  • OpenCode
  • Qwen
  • ChatGPT Desktop

AI agents can now interact with FrostWire’s desktop functionality through a standardized protocol.

Torrent Creation: Piece Sizes Up to 128 MB

The Torrent Creation Dialog now supports piece sizes up to 128 MB (previously capped at 4 MB). When creating a torrent, the dialog automatically recommends an optimal piece size based on your total content — targeting 1,000–3,000 pieces. This dramatically reduces RAM usage when seeding large files like 4K Linux ISOs.

Per-Torrent Save Location

When selecting files to download from a torrent, the dialog now shows the current save folder with Change… and Reset to Default buttons. You can pick a custom download location for each individual torrent without changing your global default.

Per-Torrent File Priority Control

The transfer detail Files tab now gives you full control over which files to download and how much bandwidth each gets:

  • “Show skipped files” checkbox — persisted globally (default ON). Skipped files appear dimmed in gray with a Download button to resume them individually.
  • Priority column — right-click any file to open an 8-level popup menu (from libtorrent’s IGNORE to SEVEN). Adjust bandwidth allocation per file within a torrent without affecting the rest.
  • All JNI calls for file metadata run on background threads, so the UI stays responsive even with torrents containing thousands of files.

Restart Button Dialog

When you change settings that require a restart (language, theme, network mode), FrostWire now shows a “Restart Now” / “Restart Later” dialog instead of just a passive message.

Clicking Restart Now gracefully shuts down and relaunches the app with the new settings applied.

YouTube Playlists & Channels

Pasting a YouTube channel or playlist URL now opens Telluride playlist search mode. Playlist partial results also appear correctly in the Video tab.

IP Filtering

The IP Filter settings pane is now fully wired to BTEngine — the clear and import buttons actually update the libtorrent ip_filter. The settings tab is no longer hidden.


No More UI Freezes

This release tackles the root cause of UI freezes across FrostWire. We identified and fixed 24 EDT (Event Dispatch Thread) violations that were blocking the UI during file I/O, torrent parsing, JNI calls, and dialog creation.

macOS Deadlock Fixes

  • Fixed a macOS EDT deadlock in FramedDialog where AppKit held awtLock during modal JDialog creation while EDT needed it for text rendering
  • Changed APPLICATION_MODAL to MODELESS in CreateTorrentDialog, SendFileProgressDialog, and EditTrackerDialog to prevent nested modal dialog deadlocks
  • Added pack() before setVisible(true) in SendFileProgressDialog, EditTrackerDialog, Options dialog, and About dialog to prevent macOS awtLock contention

Off-EDT Operations

The following operations now run on background threads instead of blocking the UI:

  • Theme loading at startup — Nimbus and FlatLaf Look-and-Feel initialization is now performed on the main thread before any Swing components exist, eliminating a consistent >2 second EDT freeze on every launch
  • Language flag image preloading — all locale flag icons are loaded into the ResourceManager cache before the setup wizard opens, so JComboBox layout no longer triggers MediaTracker.waitForID() on the EDT during startup
  • ApplicationHeader image preloading — header button background images are loaded on the main thread before MainFrame construction, preventing another MediaTracker.waitForID() stall
  • IconManager initialization — moved from the EDT to the main thread during late startup tasks
  • File launching via Desktop.open() — opening files with the OS default application now runs on a background thread, preventing X11 Desktop integration stalls on Linux when playing media
  • Transfer detail panels (General, Trackers, Peers, Pieces) — all JNI data gathering is now off-EDT
  • Native magnet URI generation — no longer blocks >2 seconds on large torrents
  • Resume data generation during pause/resume — need_save_resume_data() no longer stalls transfer actions
  • File progress computation — table painting no longer calls libtorrent file_progress() JNI on EDT
  • File I/O and torrent parsing in library table initialization
  • Directory scanning in library table updates
  • Future.get() blocking in library table selection removal
  • Recursive I/O guards added to DirectoryHolder.getFiles()
  • Drag-and-drop file existence checks — no longer triggers file.exists() syscall on EDT
  • File priority changes — all libtorrent filePriority() JNI calls run off-EDT via BackgroundQueuedExecutorService

Stability & Crash Fixes

JNI Crash Prevention

We’ve hardened the app against macOS Java 21 font-layout JNI crashes caused by malformed Unicode content:

  • Sanitize and de-HTML external text across search results, transfer names, locale labels, tooltips, and renderers
  • Normalize library text before Swing/Nimbus measures it, stripping Unicode format/control glyphs
  • Replace LineBreakMeasurer with JTextArea preferred-size calculation in tooltip UI
  • Sanitize transfer detail table strings (Files, Peers, Trackers) before Swing paints them
  • Added -Dsun.java2d.fontlayout=0 JVM argument to suppress JDK 21 SunLayoutEngine JNI warning spam during SynthComboBoxUI font layout on startup

Other Critical Fixes

  • Audio extraction crash: After extracting audio from a video download, selecting the newly added file in the library table could crash with IllegalArgumentException: Row index out of range if the file hadn’t been scanned yet. Added a bounds check to LimeJTable.setSelectedRow() to prevent this race condition.
  • Library Audio/Video nodes empty: Clicking Audio or Video in the library tree showed no files even though the Default Save Folder displayed downloads correctly. Fixed three root causes: MediaTypeSavedFilesDirectoryHolder.getFiles() was hardcoded to return an empty array instead of the cached files; LibraryMediator.scanInternal() refused to add newly downloaded files to empty caches; and SearchByMediaTypeRunnable didn’t fall back to the torrent data directory when DIRECTORIES_TO_INCLUDE was empty.
  • Shutdown hang: Added 30s timeout to LifecycleManager shutdown latch to prevent indefinite hangs
  • File size precision: BTDownload.getSize() return type changed from double to long — no more precision loss above 2GB
  • Library showing 0.0KB: File metadata loading now wrapped in try-catch with proper cell invalidation after background load
  • Library refresh (F5): Now properly re-sorts files after async lastModified load without flooding the resort executor
  • Transfer detail stale data: TransferDetailGeneral now discards stale async metadata updates when switching transfers quickly
  • Piece panel sync: TransferDetailPieces now ignores late selection updates so piece counts stay in sync with the selected transfer
  • Settings failures: UI notification now fires when settings load/save fails
  • YCCK JPEG fix: Color inversion corrected using Adobe APP14 marker Transform field
  • CreateTorrentDialog: Bottom buttons now visible on first open without requiring manual resize
  • Speed limit controls: Added download/upload speed limit adjustment buttons to TransferDetailGeneral
  • First-view detail panel: The transfer detail panel now populates correctly on first view. A HierarchyListener detects when the Transfers tab becomes visible and triggers an initial selection update, fixing the empty detail panel bug on first open.
  • Checkbox flicker eliminated: The “Show skipped files” checkbox no longer flickers or corrupts its saved setting when toggled. Fixed a race condition between the 1-second refresh timer and user-initiated clicks.
  • Checkbox lag fixed: The “Show skipped files” checkbox now responds instantly. Checkbox-initiated updates moved from the shared single-threaded BackgroundQueuedExecutorService queue to a dedicated thread (matching Android’s HIGH_PRIORITY pattern), eliminating double-queueing with the 1-second refresh timer that caused multi-second UI lag on busy transfers.
  • Checkbox truly instant: The checkbox no longer re-fetches file metadata from libtorrent on every click. A cached holder list means toggling is a pure-EDT filter operation with zero JNI calls — the table updates in milliseconds even for torrents with thousands of files.
  • Table refresh fixed: The Files tab now rebuilds its table with fresh data on every refresh instead of calling tableMediator.update(), which was a no-op for immutable pre-computed holder objects.
  • Large torrent table freeze fixed: Replaced the per-row fireTableRowsInserted storm with a single bulk model replacement (setHolders) that fires fireTableDataChanged once. The EDT no longer freezes for seconds when updating a torrent with thousands of files.
  • Torrent file listing optimized: BTDownload.getItems() no longer performs a redundant piece-checking loop on every call. For a torrent with 10,000 pieces, this eliminates 10,000 th.havePiece() JNI calls per refresh. The tracker is now initialized once and kept up-to-date by libtorrent alerts.
  • Torrent switch fixed: Selecting a different transfer now correctly updates the Files tab. Replaced the broken target != btDownload guard with a monotonic sequence counter, so stale background completions are skipped without blocking legitimate torrent switches.
  • Library tree missing files fixed: SearchByMediaTypeRunnable no longer skips disk search when the cache is non-empty. Files that existed on disk before startup (or in directories not covered by scanInternal) now appear correctly in Audio/Video tree nodes.
  • Library path consistency fixed: FileUtils.listFiles() now returns absolute paths, ensuring cache deduplication and canonical path resolution work correctly across platforms.
  • Priority popup themed: The priority popup menu now uses FrostWire’s themed SkinMenuItem/SkinMenu components for consistent dark theme rendering.
  • File progress refresh: File progress percentages now update correctly after priority changes — no more stale 0% displays.

Settings Persistence

  • Tip of the Day: The “Show Tips at Startup” checkbox now saves immediately when toggled. Previously, the unchecked state could be lost if the app was force-quit before the normal exit save path ran.
  • Setup wizard infinite loop fixed: The wizard now saves its completion state synchronously instead of asynchronously. Previously, force-killing the JVM (e.g., IDE stop button) before the background save task executed caused the wizard to run again on next startup, which in turn reset SHOW_TOTD=true every time.
  • Setup wizard no longer resets tips unconditionally: The wizard only resets “Show Tips at Startup” on actual version updates, not when it appears for other reasons (intent window, associations, etc.).

HexHivePanel Overhaul

The transfer Pieces panel (HexHivePanel) received a complete rendering overhaul:

Fixes

  • Consistent hex tiling math with the fast flat-hex path for large swarms — no more overlapping piece cells
  • Restored the 3D cube-shaded look while keeping corrected tiling math and off-EDT cached rendering
  • Rows now wrap against the full viewport width — no more missing right-edge cubes
  • No longer cancels queued renders before rasterization starts — prevents refresh starvation (blank panel)
  • Coalesces rapid refresh requests through a single background render loop — 1-second detail updates no longer invalidate in-progress rendering
  • Merges retained viewport batches using non-overlapping seam bands — no more moving white gaps between rendered cube rows

Performance

  • Renders and publishes visible viewport cubes first — the Pieces tab paints quickly before the full scrollable bitmap finishes
  • Tracks viewport movement and resizes — only renders the visible region plus directional lookahead margins instead of repainting thousands of off-screen cubes
  • Retains a full-size backing bitmap and incrementally patches new viewport batches — previously drawn cubes stay visible when scrolling back
  • Prioritizes a smaller visible-band render with directional buffer and shorter row batches — reduces transient blank patches while scrolling

Search & Download Improvements

  • Tracker list refresh: Default tracker lists updated across desktop torrent creation, magnet URLs, and CreateTorrentDialog with current reliable public trackers (opentrackr, openbittorrent, stealth.si, exodus, torrent.eu.org, moeking, explodie, coppersurfer)
  • SoundCloud search now excludes tracks not marked as downloadable — only shows content the platform explicitly allows for download
  • Idope search updated to the new idope.pics domain and filters placeholder “No results returned” API responses
  • MagnetDL search parser now accepts both raw JSON arrays and quoted JSON-array payloads
  • SlideDownload now extracts .zip downloads with zip-slip protection
  • PerformersHelper now filters hidden files alongside pad files in search results
  • QuotedStringTokenizer now supports backslash quote escaping
  • TorrentFileFilter display string now properly internationalized
  • GloTorrents search engine removed (domain gtso.cc is parked and no longer functional)

Dependency Upgrades

LibraryOld VersionNew Version
BouncyCastle1.801.83
FlatLaf3.63.7.1
SQLite JDBC3.50.3.03.51.3.0
JetBrains Annotations26.0.226.1.0
JUnit5.12.25.13.4

Cleanup

Removed dead EDT-blocking code from BTDownloadMediator, unused utility methods, ancient try/catch hacks, Thread.sleep() scroll hacks, and dozens of stale TODO comments throughout the codebase.

FrostWire for Android 3.1.1 Build 772

This release note covers everything shipped in FrostWire for Android 3.1.0 build 771 and 3.1.1 build 772.

frostwire-android-release-3.1.1-b772-plus.apk

Release At A Glance

  • 120 notable changes in total
  • 69 fixes
  • 13 improvements
  • 5 new features
  • 33 maintenance updates

Biggest Themes In This Release

  • Much stronger playback reliability, especially for cold starts, notifications, direct-file playback, album art, queue state, and now-playing UI updates
  • Better torrent and transfer stability, including previous-session restore, large torrent file lists, transfer list responsiveness, and VPN or Wi-Fi protection behavior
  • Better search and download reliability for YouTube, SoundCloud, and Internet Archive
  • Fewer ANRs, StrictMode violations, lifecycle crashes, and Android 12-14 compatibility issues
  • Safer, more modern app infrastructure with Media3, DataStore, updated dependencies, and broad deprecated-API cleanup

New Features

  • Added I2P support and I2P settings so users can route transfers through anonymous proxy infrastructure
  • Added YouTube playlist URL search and playlist-aware download flow
  • Added a terminal launcher for building, installing, and running FrostWire Android without Android Studio
  • Added a live logcat viewer to the launcher workflow for faster debugging
  • Added clearer VPN and Wi-Fi protection status feedback in the Transfers screen

Player And Library Improvements

  • Migrated the music player from the old MediaPlayer stack to ExoPlayer and Media3 for more reliable playback behavior
  • Migrated playback integration from RemoteControlClient to MediaSession APIs
  • Adopted the standard Android media notification style with output device selector support
  • Made player controls, metadata, play or pause state, repeat, and shuffle react faster
  • Fixed cold-start playback issues that could restart the first song, miss metadata, or hide the system notification
  • Fixed player notification behavior across next, previous, auto-advance, and direct-file playback
  • Fixed direct playback for freshly downloaded audio before MediaStore indexing finishes
  • Fixed album art fallback loading for direct-file playback and freshly downloaded tracks
  • Fixed the elapsed-time labels and seekbar so they refresh as soon as track metadata is available
  • Fixed My Music and Now Playing deletion flow on Android 11+ by using the system MediaStore delete confirmation flow
  • Fixed ghost entries in Recent and Favorites after deleting songs

Transfers, Torrents, And Search

  • Fixed previous-session torrent restores so old transfers reliably come back after relaunch
  • Fixed large torrent file lists that could stall, ANR, or take too long to appear in Transfer Detail
  • Fixed torrent status rendering that could freeze the Transfers list
  • Fixed transfer rows and Transfer Detail file rows getting temporarily out of sync with live state
  • Fixed transfer audio play buttons so they open FrostWire’s own player correctly
  • Fixed Wi-Fi-only and VPN guard protection behavior after Android networking API changes
  • Improved torrent and magnet handling from browsers and download managers
  • Fixed tracker edit and remove actions when the underlying tracker list changed
  • Fixed YouTube 403s, dropped headers, empty downloads, slow playback start, and file type detection issues
  • Restored SoundCloud search reliability and improved filtering of results that cannot really be downloaded
  • Restored Internet Archive downloads from search results

Performance And Stability

  • Removed dozens of ContentResolver queries and file-system operations from the UI thread
  • Eliminated multiple StrictMode violations across storage access, file opening, preference saves, and UI-triggered background work
  • Fixed crashes tied to foreground-service startup, player shutdown, rejected executor tasks, and missing native torrent libraries
  • Added safer handling for native jlibtorrent startup failures so the app stays usable even when the torrent engine cannot initialize
  • Fixed several detached-fragment and stale-activity crashes across search, profiles, playlists, settings, and dialogs
  • Fixed Android 13+ permission prompting so storage or media permissions no longer re-trigger repeatedly on resume
  • Fixed shutdown path StrictMode warnings caused by reflective task finishing

Platform And Architecture Work

  • Migrated app preferences from SharedPreferences to Jetpack DataStore
  • Added a central configuration repository for defaults, migrations, and safer preference access
  • Modernized fragment APIs, activity result flows, menu handling, notifications, and many deprecated Android platform calls
  • Updated yt-dlp, Chaquopy, Python, Firebase, AndroidX, WorkManager, Coil, and other core libraries
  • Removed outdated notification helpers, old media button plumbing, obsolete build flags, and unused 32-bit support
  • Cleaned up legacy search engines and dead code paths that no longer reflected working services

What 3.1.1 Adds On Top Of 3.1.0

  • Startup and foreground-service crash fixes
  • More reliable restore of previous-session torrents
  • Faster and safer Transfer Detail file loading
  • Fixes for My Music deletion on Android 11+
  • Fixes for now-playing clocks and seekbar updates
  • Android 13+ permission prompt loop fix
  • StrictMode cleanup for MainActivity shutdown

Bottom Line

3.1.1 is a cumulative stability release built on top of the major 3.1.0 modernization work. The biggest user-facing wins are smoother playback, more dependable torrent restore and transfer screens, better download reliability, and fewer Android-version-specific crashes and stalls.

FrostWire for Android 3.1.0 build 771: modern playback, safer downloads, and much stronger Android compatibility

FrostWire for Android 3.1.0 build 771 is a major stability and modernization release centered on one high-impact outcome: the app now behaves much more like a modern Android media and download app.

This build rebuilds the music player around Media3/ExoPlayer, restores reliable standard Android media notifications, hardens YouTube and Internet Archive downloads, migrates preferences to Jetpack DataStore, modernizes VPN/Wi-Fi protection logic, and removes a long list of UI-thread bottlenecks that could lead to freezes or ANRs.

By the numbers

FrostWire for Android 3.1.0 build 771 includes 120 documented Android release-note items:

  • 69 fixes
  • 13 improvements
  • 33 maintenance items
  • 5 new features

We were able to perform 120 updates using a ton of AI compute sponsored by your donations, thank you.

There is no separate crash: bucket in the 3.1.0 changelog, but many of the fixes are crash-class or ANR-class hardening, especially around Chaquopy/yt-dlp startup, music playback transitions, DataStore persistence, MediaStore access, and deprecated Android API migrations.

Highlights, from most important to least important

1. The music player was rebuilt around ExoPlayer and Media3

This is the biggest change in the release.

FrostWire’s Android player moved from the deprecated MediaPlayer and RemoteControlClient stack to ExoPlayer / Jetpack Media3 / MediaSessionService. That migration fixed long-standing race conditions and made the player work like a current Android media app.

The result:

  • a standard Android media notification instead of a fragile custom RemoteViews implementation
  • output device selection in the notification for Bluetooth/Cast-style routing
  • more reliable play/pause, shuffle, repeat, and metadata refresh behavior
  • much better behavior during cold start, background playback, next/previous, and auto-advance transitions

2. Android media notifications now survive real playback use

The media notification work was not just a visual refresh. It fixed a whole class of playback-control failures that made background listening unreliable.

This release fixes:

  • missing media notifications on Android 12+
  • notification disappearance during engine-service notification refreshes
  • notification loss during next/previous/auto-advance transitions
  • stale Not playing state during active playback
  • notification controls failing to keep metadata, cursor state, and queue state in sync
  • previous-track history breaking after several songs
  • playback being killed when backing out through FrostWire’s “go home” dialog

In practice, the player notification is now much closer to how people expect Spotify, YouTube Music, or Pocket Casts to behave.

3. Fresh downloads and direct-file playback now work much better

3.1.0 removes a major source of frustration around newly downloaded songs.

The app now handles audio files more intelligently before MediaStore has indexed them:

  • freshly downloaded audio can start immediately instead of waiting for slow MediaStore indexing
  • YouTube audio downloads now open in FrostWire instead of a third-party app
  • direct-file playback no longer depends on a valid MediaStore ID
  • freshly completed YouTube downloads from Transfers can replace the current song correctly
  • album art fallback works even when MediaStore IDs or album IDs are not ready yet

This means FrostWire now behaves correctly in the exact window where users most often try to play a file: right after the download completes.

4. YouTube download reliability was substantially hardened

The YouTube pipeline got a deep reliability pass.

Notable fixes include:

  • fixing the Chaquopy/yt-dlp startup crash path caused by Android-incompatible subprocess behavior
  • threading per-format http_headers through the full download pipeline so requests keep the headers YouTube expects
  • preventing malformed headers from dropping all subsequent headers
  • treating non-2xx responses as failures so FrostWire no longer leaves behind misleading 0-byte files
  • improving browser-like default headers in the OkHttp wrapper

This release also updates the Python/Chaquopy environment and the yt_dlp integration so Android playback and downloading are much less brittle.

5. Search and download sources are more dependable again

Several search and download integrations were repaired or improved:

  • SoundCloud search was restored by validating remote credentials before caching and falling back safely when necessary
  • SoundCloud result filtering was corrected to match real downloadable/streamable behavior
  • Internet Archive downloads from search results were restored, including nested archive paths for composite crawled results
  • YouTube playlist URL search was added, with playlist partial-result support in Telluride
  • FrostWire is now offered more reliably for .torrent files and magnet links from browsers and download managers

The common theme is less silent failure and better handoff from search results into actual playback or downloads.

6. Preferences and settings were modernized with Jetpack DataStore

This release migrates FrostWire away from SharedPreferences to Jetpack DataStore, with a central configuration repository and safer default handling.

Benefits include:

  • atomic preference writes
  • safer migration from older installs
  • less risk of preference corruption or type mismatch crashes
  • settings writes moved off the UI thread to reduce ANR risk
  • a single source of truth for defaults and volatile preference resets

This is one of the most important under-the-hood changes in 3.1.0, even though it is less visible than the player work.

7. UI freezes, disk I/O, and ContentResolver work were pushed off the main thread

A large part of 3.1.0 is Android hygiene work that directly affects responsiveness.

The release removes:

  • 38 ContentResolver.query() calls from the UI thread
  • 12 disk I/O operations from the UI thread
  • 9 unnecessary async roundtrips for simple in-memory reads

It also fixes multiple StrictMode violations across music, transfers, suggestions, settings, and file opening flows.

These are the kinds of changes that make the app feel less fragile even when they are not visible as a single headline feature.

8. VPN Guard and Wi-Fi Only protections were updated for modern Android APIs

Networking protections had been weakened by deprecated Android APIs.

3.1.0 fixes this by:

  • migrating network monitoring from deprecated broadcast-based connectivity APIs to NetworkCallback
  • restoring correct Wi-Fi Only behavior
  • restoring correct VPN Guard behavior
  • adding faster periodic protection-state monitoring
  • surfacing transfer-screen indicators when protections pause downloads

This is important correctness work for anyone relying on FrostWire to respect network constraints.

9. Transfers, My Music, and deletion flows were cleaned up

Several library and transfer-list correctness bugs were fixed:

  • transfer rows and transfer detail file lists now refresh against the correct live state
  • transfer audio play buttons now open the same player flow used by My Music
  • deleting songs no longer leaves ghost entries in Recent/Favorites
  • 0-byte broken downloads are now filtered out of Recent
  • track deletion avoids a lifecycle-related NullPointerException

This reduces a class of bugs where FrostWire appeared to “undo” the user’s action because the UI reloaded stale data too early.

10. New power-user and privacy features were added

The release also adds a few meaningful new capabilities:

  • I2P network integration for anonymous proxy support
  • I2P settings UI under Settings > Advanced
  • frostwire_launcher.py TUI to build, install, run, and inspect the app without Android Studio
  • live logcat viewing from the launcher

These are not the core reason 3.1.0 matters, but they make the build more capable for both advanced users and developers.

11. Android compatibility and dependency modernization continued

This build also includes a broad modernization sweep:

  • EngineIntentService moved away from deprecated JobIntentService
  • deprecated fragment/activity/notification APIs were migrated across the app
  • old custom media notification plumbing was removed in favor of Media3
  • Gradle/AGP/Python/build tooling and multiple Android dependencies were updated
  • search and media helper code was cleaned up and consolidated

That maintenance work matters because much of the 3.1.0 stability gain comes from removing old code paths that modern Android no longer treats kindly.

Types of work in 3.1.0

This release is not just “a player update.” It spans several categories:

  • Playback architecture modernization: MediaPlayer -> ExoPlayer/Media3, MediaSessionService, notification/output controls
  • Playback correctness fixes: queue sync, metadata refresh, previous/next behavior, cold-start playback, direct-file playback
  • Download hardening: yt-dlp/Chaquopy reliability, YouTube headers, 0-byte download prevention, archive.org result downloads
  • Search/source fixes: SoundCloud, Internet Archive, YouTube playlist URLs, intent filters for torrents/magnets
  • Settings/persistence modernization: SharedPreferences -> Jetpack DataStore, safer migrations, centralized defaults
  • Responsiveness and ANR prevention: main-thread query and disk-I/O removal, StrictMode cleanup, fewer async hops
  • Network protection correctness: Wi-Fi Only, VPN Guard, and modern connectivity monitoring
  • Developer and power-user tooling: I2P support, launcher TUI, live logcat

Why 3.1.0 matters

FrostWire for Android 3.1.0 build 771 matters because it fixes the seams between searching, downloading, and actually using media on a modern Android device.

Before this release, the most visible pain points were exactly where users notice breakage fastest: fresh downloads not opening correctly, notifications disappearing, playback controls getting stuck, settings writes freezing the UI, and modern Android API changes quietly breaking network protections or media behavior.

This build addresses those pain points directly and moves the app onto a much healthier foundation.

New FrostWire 7.0.3 for Desktop — Release Notes

Date: March 25, 2026
Build: 330
Urgency: High

This update focuses on critical stability improvements, memory management, and the initial infrastructure for I2P integration. We’ve also addressed several UI bugs and search logic inconsistencies to provide a smoother user experience.

Windows:
frostwire-7.0.3.windows.exe

MacOS:
frostwire-7.0.3-x86_64.pkg
frostwire-7.0.3-arm64.pkg

Linux:
frostwire-7.0.3.x86_64.tar.gz
frostwire-7.0.3.arm64.tar.gz


🚀 New Features

  • I2P Integration: Added the foundational configuration infrastructure for I2P, including a dedicated UI settings panel and registration within the options dialog
  • JDK 26: Updated to JDK 26 bundled runtime
  • Telluride Build 44: Latest Telluride Video Downloader improvements

🛠️ Bug Fixes & Stability

  • Memory Leak Prevention: Implemented bounds on previously unbounded image and icon caches to stop excessive memory consumption
  • Crash Fix: Resolved a specific crash that occurred when users pasted non-video URLs into the search bar
  • Linux Improvements: Fixed persistent tray icon issues specifically for users on KDE Plasma (#845)
  • Search Logic: Fixed the “Search Tools” filter and overhauled the logic to ensure all search filters now work independently and accurately
  • I2P Configuration: Fixed I2PPaneItem return value for applyOptions to ensure settings are saved correctly

📈 UI/UX Refinements

  • Speed Accuracy: Fixed a calculation error in the Peers Tab; download/upload speeds are now correctly converted from bytes/s to KB/s for easier reading

Note: This release is marked with High Urgency due to the memory leak and crash fixes. Users are encouraged to update immediately to ensure application stability.


📥 Download

Download FrostWire

ℹ️ About FrostWire

FrostWire is a free, open-source BitTorrent client and media player that has been actively developed since 2004. This release continues our commitment to stability, performance, and user privacy with the addition of I2P infrastructure support.

Full Changelog: View on GitHub

FrostWire 7.0.2 Released: Enhanced Privacy with VPN-Drop Protection & Smarter Search

We are excited to announce the release of FrostWire 7.0.2 (Stable) for Windows, macOS, and Linux. This update is a significant milestone for user privacy and search efficiency, introducing a robust “VPN-Drop Protection” system to keep your identity safe while downloading.

Windows
frostwire-7.0.2.windows.exe

MacOS
frostwire-7.0.2-x86_64.pkg (Intel)
frostwire-7.0.2-arm64.pkg (Apple Silicon)

Linux
frostwire-7.0.2.x86_64.tar.gz
frostwire-7.0.2.arm64.tar.gz

Whether you are a casual downloader or a power user, 7.0.2 brings a more responsive, cleaner, and safer experience to your desktop.

🛡️ Stay Protected: New improved VPN-Drop Protection

Screenshot 2025-12-28 at 2 15 16 PM

The headline feature of this release is the VPN-Drop Protection. In the world of BitTorrent, maintaining a secure connection is paramount. We’ve added a fail-safe to ensure your real IP address is never accidentally exposed.

Quick Toggle: You’ll notice a new checkbox in the status bar. This allows you to instantly enable or disable VPN-Drop Protection.

Automatic Pausing: If this setting is on and your VPN disconnects, FrostWire will automatically pause all BitTorrent transfers.

Smart Alerts: FrostWire now checks for an active VPN connection when you start a new download, open a .torrent file, or paste a magnet link. If you aren’t protected, a dialog will alert you before the transfer begins.

Performance First: We’ve optimized the logic behind the scenes (using a new VPNDropGuard system) to ensure that checking your VPN status won’t lag your computer or freeze the interface.

🔍 Better Search, Faster Results

We’ve overhauled how FrostWire sorts your search results to help you find the highest quality files in less time.

Relevance First: Search results are now prioritized by keyword matches first, followed by seed counts and popularity. This ensures that the most relevant and “healthy” files stay at the top of your list.

Bug Fix: We’ve squashed a bug where seed counts were occasionally disappearing from the search UI. You’ll now have full visibility into the health of every file before you click download.

🎨 Clean & Compact UI

We believe a powerful tool should also be a beautiful one. FrostWire 7.0.2 features a more compact status bar layout. By reducing spacing and using a smaller font for the VPN indicators, we’ve freed up screen real estate while still keeping your vital connection stats front and center.

There is even a handy, clickable “VPN” link in the status bar that takes you directly to information on how to better protect your privacy.

Changelog Highlights:

Improved: Search result sorting (Keyword relevance > Seeds/Popularity).

New: VPN-Drop protection checkbox in the status bar.

New: VPN status checks when starting downloads or opening magnet links.

Fix: Resolved issue with disappearing seed counts in search results.

Optimization: All VPN-related logic moved to background threads to prevent UI blocking.

UI: Minimalist spacing for VPN and status indicators.

Download FrostWire

FrostWire for Android 3.0.14: Critical Stability Fixes & Engine Optimization

Just in time for the new year, we are rolling out a vital update for our Android users. FrostWire 3.0.14 (build 768) is now available, and it addresses several critical “day-one” issues introduced with our recent V2 architecture overhaul.

This release focuses on making sure the app starts correctly, downloads reliably, and accurately reports the status of your transfers.

What’s Fixed in Build 768?

🛠 Fixing the “Error” Status Bug

Many users reported that newly started torrents would immediately show an “Error” status even when the download was healthy. We found that the app was occasionally reading from an outdated status cache. We’ve implemented a fix to invalidate that cache immediately upon starting a transfer, ensuring you see the actual download progress instead of a false error.

⚡ Solving Initialization Crashes

We’ve eliminated two major race conditions that occurred during the app’s startup sequence:

  • Port 0 Binding Failure: Previously, the BitTorrent engine (BTEngine) would sometimes try to start before your settings were loaded, causing it to fail by trying to connect to “Port 0.”
  • Session Initialization: We’ve ensured the ConfigurationManager now blocks and finishes loading preferences before the engine starts, preventing session-related crashes.

🔍 Restoring Search-to-Download Functionality

Following our recent search architecture consolidation, some results from popular sources (like TPB, 1337X, and MagnetDL) weren’t being recognized as torrents.

  • We have added support for the new CompositeFileSearchResult interface.
  • This ensures that when you click a search result, the download starts immediately as intended.

📈 Maintenance & Core Updates

We have refreshed our core dependencies to ensure maximum compatibility with the latest Android devices:

  • yt-dlp Updated to 2025.12.08: Essential for high-speed cloud video downloads.
  • Gradle Plugin 8.13.2: Optimized build performance.
  • Library Updates: Updated Firebase BOM (v34.7.0), AndroidX ExifInterface (v1.4.2), and SwipeRefreshLayout (v1.2.0).

How to Update

  • Direct Download: Visit FrostWire.com to download the latest APK directly.

If you’ve been having trouble with downloads not starting or seeing unexpected errors in your transfer list, this update is highly recommended. Thank you for helping us make FrostWire better by reporting these issues!

Happy New Year and Happy Downloading!
— The FrostWire Team