vX.Y.Z releases the floe CLI and the container images for the server and web app you can run yourself. desktop-vX.Y.Z releases Floe Desktop for Windows. The web app at floe.one is on neither line: it runs the newest code as soon as it is merged, so a web app change can be live there before the vX.Y.Z entry that lists it. The two lines never need to match.
Versions work together down to these floors, as measured against the current code. By room code, floe sends and receives both ways from v1.5.5. By link, it does from v1.7.5, and v1.6.0 and older cannot read a # link at all. floe send --to needs floe 1.12 on a link that holds a link key. A floe receive older than 1.12 cannot take a floe send --link-only, and from 1.10.8 it says to update. A v1.0.0 receiver ends with an empty file from any sender of v1.10.0 or later. The web app, floe 1.12 and later and Floe Desktop 1.1 and later speak protocol version 2 and still accept version 1. Request links need a current Floe Desktop and a server that offers them.
Each entry lists the parts it changed. Filter on the right to see only the ones you use.
WebDesktopCLI
The home page’s privacy list now shows the main things
- The privacy section lists the main things the signaling server handles and links to the full list in Security and privacy, which now also names the Origin check.
- The privacy policy now says that a link from
floe1.12 and later and Floe Desktop 1.1 and later carries a link key, that older ones neither make nor check it, and that the proxy in front of the signaling server keeps no request log. The docs say the same. - The floe.one download page now offers Floe Desktop 1.1.0.
- The home page’s answer to “Is this secure?” now says what the link key checks and when you are still trusting the signaling server.
- The home page section buttons now move keyboard and screen-reader focus into the section, and section scrolling follows the system’s reduced-motion setting. Contributed by @Himanshu-singh04.
- On the main page, a folder you drop is now sent with its structure: each file is listed by its path, such as
photos/day1/b.txt, and Floe Desktop orfloerebuilds the folder. Create secure link stays off while the folder is read. A folder used to be refused at the drop. Contributed by @Detoy. - On a request link’s page, adding files now keeps two different files that share a path and a size, such as one name picked from two folders with Choose files, or two scanners’
Scansfolders. The second used to be left out without a word and never sent. A file picked again is still added once. Contributed by @redwing509. - When the connection fails during a send, the sending page now says “Connection interrupted” with the banner “The connection closed before the transfer finished.” once the receiver has accepted a file. If the failure came early in a file, it used to show the words for a send that never started, such as “Connection lost. The other device may have closed the tab.” Contributed by @X1NPAR1.
- Desktop: on the Send tab, keyboard focus now stays on Cancel when a send starts, and on the Files or Text tab when it ends or is canceled, instead of falling to the page. Contributed by @Detoy.
- CLI:
floe receive -o ~/Downloadsnow saves into the Downloads folder in your home folder when the~reachesfloeas typed, as it does in Windows PowerShell, incmd.exe, inside quotes and after--output=. It used to save into a new folder named~in the current folder. Contributed by @NopeCharon. - CLI:
floe sendnow sends a file once when its path is given twice, as infloe send a.txt a.txt,floe send ./a.txt a.txt, a folder named twice, or a glob that also matches a named file. It used to send it twice, so for one 5-byte file theSendingline read2 files · 10 Bytesandfloe receivesaved the second copy asa (1).txt. Contributed by @ShahadatTest.
A link from Floe Desktop now carries a link key that no server receives, and a receive or a request link refuses a sender that cannot prove it holds it
- A link from Send and a request link now carry a random link key in the part after the
#, which no server receives. Floe checks it against the connection’s certificates before any file is accepted: a receive of such a link and the host of a request link refuse a sender that cannot prove it holds the link key, with nothing saved and no prompt shown. Send only detects: it stops when the other side’s proof is wrong and goes on when no proof comes, so a server that plays a receiver with no link key still gets the whole file. Nothing changes when the check passes. A request link says “A sender couldn’t be confirmed and was disconnected” and keeps waiting, and closes after 5 such senders. A code carries no link key, so a receive by code is as it was. - In Receive, a link whose link key lost its name now reads as incomplete, as a link cut short does. Something that encoded the
#, or droppedk=, used to leave a link that joined with no check. - When a receiver stops a send after it has answered, Send now says they stopped the transfer. Two of those stops used to say Nothing was sent, which is no longer sure once a file may have gone.
- The role a signaling server names and a broken offer now each read as a fixed line.
- A connection that goes quiet for a few seconds while it is being set up now keeps trying. It used to stop with “Couldn’t connect the two devices” on a path that was about to work, which a slow relay could cause.
- A receiver now stops when a sender numbers a file past the end of its batch. No honest sender does this.
- When a file you are sending can no longer be read (moved, deleted, unplugged), the receiver is now told why, in the same words the browser sender already uses, instead of being left to read a network fault. Contributed by @bfs2021.
- A pipe, a socket or a device you add to a send now stops it with
cannot send <path>: it is a pipe, a socket or a device, not a file, and inside a folder such an entry is left out. A pipe or a device used to be sent as an empty file, and a socket in a folder stopped the send. Contributed by @yigitbuyukeren. - With Save to blank, a receive now saves to the Downloads folder Windows names, wherever you moved it, and a request link saves to the
Floefolder inside it. They used to save under your home folder, even when Downloads was on another drive or a network share. If that folder is missing or cannot be reached, Floe still uses the home folder’s Downloads, or the home folder itself. Contributed by @ayushdwivedi-stack. - In History, a receive by code now lists its empty files by name, where one empty file received alone used to read “0 files”. Contributed by @Detoy.
Ctrl+O,Ctrl+V,Ctrl+HandCtrl+Rnow work while a Settings switch, or Auto-accept on a request link, has focus. They used to do nothing there, because a switch is a checkbox and the shortcut handlers counted every input as a text field. Contributed by @Ptraaah.- In Settings, Hide my IP address and Contribute to global stats now switch back when Floe cannot save the change, as the other switches already do. They used to keep showing the new setting while a request link went on with the saved one.
- A
desktop.jsonsaved by Windows PowerShell 5.1 now reads like any other. PowerShell starts the file with a byte-order mark, in UTF-8 fromSet-Content -Encoding utf8and in UTF-16 from>andOut-File, and Floe used to treat it as unreadable: it kept a copy asdesktop.json.badand went back to the default server address and Hide my IP address. A file that still cannot be read is kept asdesktop.json.bad, as before. Contributed by @yigitbuyukeren. - In Settings, Test now tells you to use
https://when anhttp://address redirects to HTTPS on the same host. Contributed by @Vanshchandel17. - Pasting copied files into Send now locks its Windows clipboard calls to one operating-system thread, preventing the clipboard from intermittently staying open when Go switches threads between calls. Contributed by @ayushdwivedi-stack.
A link from
floe now carries a link key that no server receives, and floe receive and the web app refuse a sender that cannot prove it holds it- A link from
floe sendnow carries a link key that no server sees, andfloe receiveandfloe send --torefuse the other side, with nothing saved or sent, when it cannot prove it holds that link key. A code carries no link key, so a receive by code is as it was, and a link from an older Floe has none to check. A plainfloe sendonly detects: it stops on a wrong proof and goes on when no proof comes, so a server that plays a receiver with no link key still gets the whole file.floe send --link-onlymakes no code and names no file until the receiver has proved it too. A link typed where a file path goes is no longer printed back. A link now holds an&, so put it in quotes when you pass it tofloe receivein a terminal, asfloe sendsays under the link. floe send --tono longer saysNothing was sent.when a drop stops after the other computer has accepted and no file was saved, because part of a file may have gone by then. It used to say so, for example when their disk filled up during the first file, and when you pressed Ctrl+C there.floe receiveandfloe send --tonow read a link whose link key lost its name as incomplete, as a link cut short is, and so does the web app. Something that encoded the#, or droppedk=, used to leave a link that joined with no check.- When a receiver stops a send after it has answered,
floe sendnow saysThey stopped the transfer.Two of those stops used to sayNothing was sent, which is no longer sure once a file may have gone. - A signaling server’s error frame, the role it names and a broken offer now each read as a fixed line, and
floeno longer prints the WebRTC library’spcanddatachannellines unless aPION_LOG_level is set. - A connection that goes quiet for a few seconds while it is being set up now keeps trying. It used to stop with
connection failed (state: disconnected)on a path that was about to work, which a slow relay could cause. - A receiver now stops when a sender numbers a file past the end of its batch, in
floeand in the browser. No honest sender does this, and the browser used to show it as, for example, “Receiving file 9 of 3”. - When a file
floe sendis sending can no longer be read (moved, deleted, unplugged), the receiver is now told why, in the same words the browser sender already uses, instead of being left to read a network fault. Contributed by @bfs2021. - A pipe, a socket or a device named directly now stops the send with
cannot send <path>: it is a pipe, a socket or a device, not a file, and inside a folder such an entry is left out. A pipe or a device used to be sent as an empty file, and a socket in a folder stopped the send. Contributed by @yigitbuyukeren. - On macOS and Linux, closing the terminal or losing an SSH session during a transfer now ends it the way Ctrl+C does:
Canceled.and exit code 130, with the other side told. It used to stop the process at once, leaving the.partfile and making the other side wait out its timeout. A program started withnohupstill survives a closed terminal. Contributed by @yigitbuyukeren. floe sendandfloe receivenow stop at once withError: --iface matches no network interface on this computer; check the name, or drop the flagwhen none of the names passed to--ifacematch a network interface. They used to pair first and then fail to connect, which spent the code. Contributed by @redwing509.floe updatenow installs a release only when its tag is exactlyvX.Y.Z. On any other name, such as9.9.9orv1.2.3-rc1, it downloads nothing and stops withError: The latest release has an unexpected version name, so floe update stopped. Reinstall with the steps at floe.one/docs/cli/installation instead.It used to install a release under any tag name. The hint infloe versionignores such a name too, whether it comes from GitHub or from the answer it saved earlier.- The install scripts now stop when they cannot check the download:
install.shon a machine with neithersha256sumnorshasum, and both scripts whenchecksums.txthas no line for the archive. They used to print a warning and install the file unchecked. The scripts are served from floe.one, so this is already live and needs nofloeupdate. install.ps1now really checks the archive’s SHA-256. GitHub serveschecksums.txtas binary data, which the script split into numbers instead of lines, so (measured in Windows PowerShell 5.1) it found no line for the archive, printedWARNING: Checksum not found, and installed the file unchecked, even one that did not match. It now printsChecksum verified.after comparing the hash. If you installed with this script, running it again gets you a checked copy.- Web app: a link made on floe.one now carries a random link key in the part after the
#, which no server receives. A browser that opens such a link checks that the sender holds the same link key, tied to the connection’s certificates, before it accepts a file, so a signaling server that steps in between is caught by the receiver, and the page says it could not confirm who sent the link. Nothing changes when the check passes. A sending page does not yet refuse a receiver that cannot show the link key, becausefloebefore 1.12 and Floe Desktop before 1.1 are such receivers, so a server that plays one gets the whole file and the page says the files were sent. - Web app: a page opened from a link with a link key now stops after 30 seconds when the other side connects and sends nothing, and says it could not confirm who sent the link. It used to wait for as long as the tab stayed open.
- Web app: once a page has said it could not confirm the other side, it keeps saying so. Losing the connection to the server, or someone else opening the link, used to clear that message and put the page back to waiting.
- Web app: the page a request link opens now reads a link that carries a link key, which no server receives, and names no file until the computer that made the link has proved it holds it. Without that proof it sends nothing and says it couldn’t confirm their computer, or, in a browser that cannot read the connection’s certificates, that this browser can’t check the link. A request link with no link key, which is every link Floe Desktop 1.0.x makes, works as it did.
- Web app: on the page a request link opens, a drop that stops after the other computer has accepted no longer says Nothing was sent. when no file was saved, because part of a file may have gone by then. It used to say so, for example when their disk filled up during the first file.
- Web app: a link cut short now opens the Link Invalid card. A link cut right after its
room=used to open the sending page. - Web app: the analytics script now loads from floe.one itself, as a copy of Umami’s tracker that was read through first, and the browser refuses to run that copy if any of its bytes have changed. It used to load live from Umami. Its reports still go to Umami, and they no longer carry the page title.
- Web app: the site’s service worker now uses its stored copy of a build file only when the request for that file fails. It used to answer from that copy for as long as the browser kept it, so anything written to that store on floe.one would have kept running across new versions of the site. This update clears that store, so the site can open without a network again once it has loaded once with one.
- Web app: a click recorded in an error report no longer holds the label of what was clicked, so the Remove and Download buttons no longer put a file’s name in the report.
- Web app: the room link is now removed from an error report when a script on the page throws text or an object that holds it, or sends it to another address as part of a request. It was removed from a thrown error’s message and from the page’s own address already.
- Web app: on the home page, the Checked on arrival tile now says browser, CLI and Floe Desktop receivers confirm delivery. It used to leave out the browser, which has confirmed delivery since v1.11.2. Contributed by @abhi478jeetur-rgb.
- Web app: the receiving page now lets go of the screen wake lock once every file has arrived or its receive stops, and the sending page lets go when its send stops. It used to hold the lock until the connection closed, so a phone that received from a computer’s browser kept its screen on while the sending tab stayed open. Contributed by @SanjayK075.
- Web app: with relay fallback on, a main-page send of 2 GB or less now starts as soon as the devices connect, instead of 2 seconds later. Contributed by @Detoy.
- Self-hosting: a request link from Floe Desktop 1.1 holds its link key behind a dot after the room id, and an older web image reads that as an incomplete link. Update the web image to 1.12.0 before Floe Desktop 1.1 reaches your users, because the Microsoft Store updates it on its own, and a web image moves only when you pull it, and never while
FLOE_IMAGE_TAGnames an older version. What an older web app shows lists what an older image does with a link key. - Self-hosting: the signaling server now logs one line when a call to Upstash Redis fails,
Upstash counter read failed (...)for the startup read andUpstash counter update failed (...)for an update, with a reason such asstatus 401,ENOTFOUNDorTimeoutError, and no more until a call succeeds. A wrong or read-only token, a URL withouthttps://, an unreachable host and a timeout used to look like a working counter until a restart dropped the total back. Contributed by @GabrielPdoCarmo. - Self-hosting: the signaling server now logs one line at startup for each pair of variables that has only one of its two set:
TURN_SECRETandTURN_DOMAIN,CLOUDFLARE_TURN_KEY_IDandCLOUDFLARE_TURN_KEY_API_TOKEN, orUPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN. The line names the pair and what is off, and never a value. The feature stays off as before, but the server used to say nothing about it. Contributed by @sudhanshukumar03. - Self-hosting: with your own coturn, a
TURN_DOMAINthat holds more than a host name, such ashttps://turn.example.comorturn.example.com:3478, now turns the coturn relay off and logsTURN_DOMAIN holds more than a host name, so the coturn relay is off. Set it to the host name alone, such as turn.example.com.at startup, and the server hands out the default STUN servers instead, so transfers that do not need a relay go on. It used to build ICE URLs that browsers throw on and the CLI and Floe Desktop refuse, so no transfer started, and nothing was logged. Contributed by @redwing509. - Self-hosting: the published images are rebuilt as
1.12.0, with the web app and server changes above. If you pinnedFLOE_IMAGE_TAG=1.11.7, move to1.12.0.
“Reset all settings?” now opens with keyboard focus on Cancel, so Enter there resets nothing
- In Settings, Reset now opens Reset all settings? with keyboard focus on Cancel, as Start over? and Close Floe? already do, so a screen reader moves into the question and
Entercloses it without resetting anything. Focus used to stay on Reset behind the question: the nextTabwent to the Settings screen behind it, andEnterpressed Reset again. Contributed by @hanshapd.
A file added twice on the main page is now listed and sent once, its FAQ questions are headings, and a self-hosted server given a port Node refuses now stops with an error
- On the main page, a file you add again, by picking it again or by dropping it after picking it, is no longer listed a second time, so it is sent once and counted once in the count and total above the list. The page tells files apart by name, size and modified time: two files with the same name are both kept when either of the others differs, and two different files that match in all three are listed once. Such a file used to be listed and sent twice, and Floe Desktop and
floesaved the second copy under a numbered name such asreport (1).pdf. Contributed by @dharamdan01. - On the main page, FAQ questions are headings for screen-reader navigation, and each question button is linked to its answer. Contributed by @Martin-e60.
- Self-hosting: a signaling server given a
PORTthat Node refuses, such as70000or3001.5, now writesHTTP server error:and exits with code 1, as it does when its port is taken, so a supervisor such as systemd withRestart=on-failuresees the failure. It used to logUnhandled error (uncaughtException), server still serving:while nothing was listening, then exit with code 0, which reads as a clean stop. Contributed by @OKAN-SOFTWARE. - Self-hosting: the published images are rebuilt as
1.11.7, with the web app and server changes above. If you pinnedFLOE_IMAGE_TAG=1.11.6, move to1.11.7. - CLI:
floehas no visible changes in this release. Its version moves with the images, and it transfers with every other Floe version as before.
A screen reader now hears a failed send or receive, finds the progress bar and knows which view is open, and History’s Clear keeps keyboard focus
- When a send or a receive by code fails, a screen reader now reads the red line under the card as soon as it appears, such as “Error: Both people need Floe open at the same time”, where it used to say nothing until the line was found. Contributed by @Mittalnew.
- While a send or a receive by code runs, a screen reader now finds the progress bar, names it by the line beside it, which starts like “[2/3] report.pdf - 42%”, and reads how far it has got, where the bar was invisible to it. Contributed by @HarshRajSinghania.
- A screen reader now says which of Send and Receive is open, and whether the Send view is set to Files or Text, where it used to read the same plain buttons whichever was selected. Contributed by @Mittalnew.
- In History, keyboard focus now stays with Clear’s question: it moves to No when the question opens, back to Clear after No, and to the “No transfers yet” line after Yes, where each answer used to drop keyboard focus to the page. Contributed by @LetMeSleep8h.
A self-hosted web app whose signaling server address has no
http:// can now reach the relay, and the web app and floe get screen-reader, keyboard, wake lock and tab-completion fixes- When the web client’s signaling server address is set without its scheme, such as
192.168.1.10:3001inNEXT_PUBLIC_SOCKET_URLor in the Unraid template’s Signaling Server URL, the page now gives it the page’s own scheme, as its live connection already did. With such an address the relay list never loaded, so peers that need a relay could not connect, and the global counter and the receiver’s byte report failed with nothing in the page or the logs to say why. Contributed by @Detoy. - Web app: on the main page, keyboard focus on the connection badge’s Learn more link now shows its tooltip, where Tab used to land on a link nobody could see. Contributed by @swastiktawate.
- Web app: the main page keeps the screen awake only while a transfer wants it. Coming back to the tab used to take the screen wake lock again whenever the connection was up, so an idle or finished page kept the screen on. A send started while the tab was hidden still gets its lock when the tab comes back. Contributed by @LetMeSleep8h.
- Web app: on the main page, once a link is created, a screen reader now names the QR button by the words on it, “Show QR” or “Hide QR”, and says whether the QR code is open, where it used to call it “Toggle QR code”, words that appear nowhere on screen. Contributed by @vaishaldsouza.
- Web app: on the main page, a screen reader now says which of the header’s About, CLI, Desktop and FAQ buttons is the section you are reading, where only the filled highlight showed it. Contributed by @vaishaldsouza.
- Web app: when a link opens the “Link Invalid” card, a screen reader now reads the card’s heading and its sentence, “This link is incomplete, already in use, or locked to the networks that first used it.”, as soon as the card appears, where the card used to replace the receive steps without a word. Contributed by @ayushdwivedi-stack.
- CLI: tab completion now offers interface names for
--iface, offers only folders for-oin Bash and Zsh, and stops offering files where a code, a link or a server address goes. Contributed by @SauravMukherjee44. - The published images are rebuilt as
1.11.6, with the web app changes above. The server’s code is the same as in 1.11.5. If you pinnedFLOE_IMAGE_TAG=1.11.5, move to1.11.6.
A browser receive that runs out of room for its files now says so, and a screen reader gets the file buttons, the progress bar and the red banner right
- In Chrome, Edge and other browsers built on Chromium, a receive that stops because the browser had nowhere left to keep the files, most often in a private window, now says “This browser ran out of room for the files it is receiving” and suggests a normal window. It used to say the browser ran out of memory and pointed only at Floe Desktop and the CLI. Troubleshooting has the steps. Usage analytics records this stop as
storage-full, a ninth fixed reason label, as Security and privacy lists. - A screen reader now names each file’s remove and download button after its file, as “Remove report.pdf” or “Download report.pdf”, where it used to say only “button” or “link”, and it no longer reads a file’s name twice. Contributed by @Ulaganathan0709.
- While a transfer runs on the main page, a screen reader now names the progress bar by the words beside it, such as “Sending file 1 of 3…”, and reads how far it has got, where it used to announce an unnamed progress bar with no value. Contributed by @rootsiemen.
- When the main page shows its red banner, a screen reader now reads the sentence as soon as it appears and names the banner’s X “Dismiss”, where it used to say nothing until the banner was found and called the X only “button”. Contributed by @BillWGong.
- Self-hosting: the web client’s image now checks its own health every 30 seconds, as the server’s image already does, so
docker compose psand dashboards such as Portainer show whether it is healthy, anddocker compose up --waitwaits until the web app answers. Contributed by @sonwCode. - Self-hosting: the signaling server takes body-parser 2.4.0, the fix for GHSA-27r3-jxmh-p828, in which bytes trailing a compressed request body could raise an error with no handler of its own. The server’s last-resort error handler logs such an error and keeps serving, but update anyway.
- Self-hosting: the published images are rebuilt as
1.11.5, with the changes above. The client image moves Next.js to 16.4.2 and React to 19.3.1. If you pinnedFLOE_IMAGE_TAG=1.11.4, move to1.11.5. - CLI:
floeitself has no changes in this release. Its version moves with the images, and it transfers with every other Floe version as before.
The window no longer goes blank after an error or on a file named like
notes.constructor, and a screen reader now gets three controls right- Picking, dropping or pasting a file or folder whose name ends in
.constructoror.__proto__, in any letter case, no longer leaves the window blank until Floe is restarted. Its row now shows the plain file icon. Contributed by @Ulaganathan0709. - While a send is in progress, a screen reader now says that the “3 items” row expands and whether its list of files is open, where it used to say only “3 items, button”. Contributed by @boonstraworks.
- If something goes wrong while the window is drawn, Floe now shows “Something went wrong” with Reload window and Close Floe, where the whole window, title bar included, used to go blank until Floe was restarted. Close Floe also ends a transfer or request link still in progress. Contributed by @sonwCode.
- On Receive, a screen reader now names the two fields by their captions, “Code or link” and “Save to”, where it used to name them by their placeholder text, “amber-otter-cloud” and “Downloads (default)”. Contributed by @carolinayumifujii.
- While a send waits for the receiver, a screen reader now names the QR button by the words on it, “Show QR” or “Hide QR”, and says whether the QR code is open, where it used to call it “Toggle QR code”, words that appear nowhere on screen. Contributed by @Jah-yee.
A very large receive no longer fills the storage History is kept in, and closing Floe while a setting is saved no longer freezes the window
- The window no longer goes blank when the storage it keeps History in is full. A receive by code now keeps the first 200 file names in its History row, as a request link drop already does, so a very large folder no longer fills that storage, and an expanded History row lists at most its first 200 names, older rows included. The row still counts every file.
- Closing the window while a setting is being saved no longer leaves the window not responding when your AppData folder is on a slow or network drive, and the setting is still saved.
- After a second copy within a moment of the first, the check mark of Copy code and Copy link, and the “Copied” of Settings > About, now stay for their full time instead of going early.
- Floe Desktop reads at most 64 KiB of the server’s answer for connection details or a short code, so a server that answers with far more can no longer make it use gigabytes of memory. A Floe server’s answer is under 1 KiB. A longer one now counts as unreadable: a transfer goes on with STUN only, Test in Settings says the server didn’t return usable connection details, and Send shows the link without a code.
The web app shows a green check mark when every file’s SHA-256 matched, and
floe and the signaling server hold firmer limits- When every file’s SHA-256 matched, the check marks in front of “3 files received” on the receiving page and beside “All Files Sent!” on the Send page are green, as in Floe Desktop. The line “SHA-256 matched” that sat under them is gone; a screen reader still reads it. When a file could be checked by its size only, the check mark is gray, where it was green every time.
- On the Send page “All Files Sent!” turns green with its check mark when the receiving app reports that every file matched, usually a moment after the last byte leaves. Until then, and for good with a receiver that sends no such report, both stay gray.
- A request link’s page still says “Their app reports every file’s SHA-256 matched.”, and
floe sendandfloe receivestill printVerified SHA-256 matched. - In a browser without WebRTC, such as Tor Browser or Firefox with WebRTC turned off, a receiving page now says so in its red banner and does not join the room, so the link still works when opened in another browser. A sending page says so as soon as it loads. The sentence stays up through a reconnect.
- A send whose connection closed just as its last file finished now says “Connection lost. The other device may have closed the tab.” instead of “All Files Sent!”, because the end of that file never reached the receiver.
- CLI:
floereads at most 64 KiB of the server’s answer for connection details or a short code, so a server that answers with far more can no longer make it use gigabytes of memory. A longer answer counts as unreadable: the transfer goes on with STUN only and the usual warning,floe sendshares the link without a code, andfloe receivesays it could not resolve the code. - CLI: on Windows, a
floe updatewhose download failed partway no longer leaves the partial download in your temp folder. - Self-hosting: a
TRUSTED_PROXY_COUNTthat is a word or a negative number still counts as 0, and the server now says so in one line at startup. - Self-hosting: a
CLIENT_URLwritten with a trailing slash, such ashttps://app.example.com/, no longer shuts your own web app out. - Self-hosting: the example coturn configuration refuses to relay to private, loopback, link-local and other reserved addresses. A
turnserver.confyou already made does not change: copy the new lines in from the example. If a device that uses the relay can be on the relay’s own private network, such as a relay at home that you also use from home, also uncomment the example’sallowed-peer-ipline for that network, as the TURN relay page explains. - Self-hosting: the signaling server sends the stats counter’s bytes to Upstash Redis one call at a time, adding the bytes reported in the meantime to the next call, so a stalled Upstash no longer holds an open call for every report.
- Self-hosting: the signaling server now disconnects a browser connection that has stopped reading once about 1 MB is waiting for it, as it already did for the CLI and Floe Desktop, so a flood aimed at such a connection no longer piles up in the server’s memory until the connection times out. A page cut off this way stays disconnected until it is reloaded.
- Self-hosting: when you build the web app yourself, as an image or with
pnpm build, the Sentry build plugin no longer sends Sentry a report about the build: a session, and sometimes a timing sample, never any visitor data.NEXT_TELEMETRY_DISABLEDdid not turn it off. - Self-hosting: the published images are rebuilt as
1.11.4, with the web app and server changes above. The client image moves@sentry/nextjsto 11.8.0, so if you send its reports to a Sentry project of your own, some span fields arrive under their 11.x names. If you pinnedFLOE_IMAGE_TAG=1.11.3, move to1.11.4.
Floe Desktop 1.0.0: Floe Desktop and request links are out of Beta
- Floe Desktop and request links are no longer labeled Beta: Request link under Receive has no Beta tag. How request links work is unchanged, and Floe’s server can still turn them off for everyone.
- While a request-link drop arrives, Floe Desktop keeps a small record of the files it saved, so a drop Floe is closed during still gets its History row. When Windows refused a write of that record, for example while an antivirus scan held the file, the files it covered waited for the next file to arrive, and a drop that Windows ended right then could show fewer saved files than it had. The write is now tried again a second later, up to five times.
Request links are out of Beta: the request link page no longer shows a Beta tag
- The request link page no longer shows a Beta tag beside “SEND FILES THROUGH THIS LINK”. It still says “Works in current Chrome and Edge on a computer.” under its heading.
- The home page, the download page, the FAQ, the terms and the privacy policy no longer call Floe Desktop or request links Beta. The terms now say that Floe can turn request links off for everyone at any time.
- Self-hosting: the published images are rebuilt as
1.11.3, with the web app changes above, so a self-hosted request link page loses its Beta tag too. The server andfloeare unchanged apart from their version number. If you pinnedFLOE_IMAGE_TAG=1.11.2, move to1.11.3.
A request-link drop Floe was closed during now shows what it saved, and quitting during a receive no longer leaves an unfinished file behind
- Quitting Floe Desktop while a piece of a received file was being written could make it wait five seconds before it closed, and leave the unfinished
.partfile in the folder. It now closes without the wait and removes the.partfile. - A request-link drop that Floe was closed during, by you or by Windows, now shows on the next launch as stopped, for example “Floe was closed · 4 of 12 files saved”, with Show in folder, and adds its row to History. The files it saved had no History row.
- On Windows 10, a file whose name begins with a reserved device name and a dot, such as
aux.horcon.txt, is saved with an underscore in front (_aux.h), in a receive and in a request-link drop, and so is a request link label such ascon.notes, which names the folder each drop is saved in. Windows 10 opens such a name as the device, so the receive stopped at that file, and with such a label every drop stopped before a file was saved. Windows 11 keeps the names as sent. - A send now reports at once a receiver that stops it while the send is waiting for that receiver to take in more data. The reason showed only once the receiver took in more data, which could take a minute or more. If it took in nothing, the send ended after a minute with “The connection dropped before the transfer finished” in its place.
- A send their Floe stops because a file name or folder path is too long to save now reads “A file name or folder path is too long for their computer. Shorten it or zip it first”. It named only a folder path.
- A request-link drop stopped by a path too long for Windows now reads “A file name or folder path was too long for Windows”, because one long file name stops it too. It named only a folder path.
- Make link now checks that Floe can write in the Save to folder, and says “Couldn’t use that folder” when it cannot, as it does for a missing drive. A folder such as Program Files made a link that failed at the first drop.
- Against a Floe server from before request links, Make link now says “This Floe server doesn’t offer request links”. It said “Request links are off on this server”, which no setting on that server could change.
- “Missed a request at” and “Link ended at” now give the date when it was not today, for example “Link ended at Oct 15, 3:42 PM”. A link can last 7 days, and a time alone read as today.
- Cancel drop now reads Stopping and takes no second click until the drop has stopped, which can take a few seconds. Nothing on screen said the click was taken.
- A request-link drop with no label that saved no file is titled “Nothing saved” in History. It was titled “0 files”.
- On a request link made with Auto-accept, a drop that asks because Floe could not tell whether the connection is relayed now says “Asks because Floe couldn’t check the connection”. It asked with no reason.
- A request link made with Auto-accept on a drive that cannot carry Windows’ downloaded-file mark, such as a FAT32 or exFAT USB drive, now reads “Ends today, 2:05 PM · Asks first, Windows can’t mark files on E:” while it waits. It said “Accepts automatically”, though every drop asked.
- A request-link file whose name already ended in
.floe-blockedwhen it was sent no longer counts as a file Floe renamed. The finished drop said it had renamed it, and Show in folder asked first because of it. - The folder name on a finished request-link drop keeps its date, time and any number such as
(2)whole, and a label in Chinese, Japanese, Korean or emoji is shortened to fit. A wide label pushed the time out of view. - After Decline, keyboard focus goes to “Request declined”, with Keep waiting one Tab away. A held Enter no longer presses Make another link or Keep waiting. Focus no longer moves to Make another link when a link ends long after a Retry now that did not reconnect, and no longer takes back a click made right after Close link or Cancel drop.
- Send with Floe in File Explorer now shows for any number of selected files. Windows hid it when more than 15 were selected. An entry an earlier Floe Desktop added is brought up to date the next time that copy starts.
- Open on a received file whose name holds
#or%now opens that file. It could open the wrong thing or nothing. - The Settings gear in the title bar now waits while Close Floe?, Start over? or Reset all settings? is open, as Ctrl+, already did. It opened or closed Settings under the question.
- On a PC without the Microsoft WebView2 runtime, a failed download of its installer now shows an error instead of closing Floe Desktop at once. The app is now built on Wails 2.16 and Go 1.27.
On Windows, stopping a receive partway through a file no longer leaves the unfinished file behind, and
floe names the server’s connection limit instead of a lost server- On Windows, a Ctrl+C in
floe receivethat landed while a piece of a file was being written could makefloewait its full five seconds before it exited, and leave the unfinished.partfile in the folder. It now exits without the wait and removes the.partfile. floe sendandfloe receivenow end withError: the server is limiting connections from this network. Wait a minute and try again.when the server turns the connection away by its limits on connections from one network. They saidconnection closed before the server assigned a role, orfailed to join room: websocket: close sent, as if the server had gone.floe send --toprints the same sentence.- A file name or folder path too long for the receiving computer, one long file name with no folder included, now ends
floe sendwithError: A file name or folder path is too long for their computer. Shorten it or zip it first.(floe send --toprints it withoutError:, then how many files were saved, such asNothing was sent.), and a pickfloe send --tocannot describe ends withA file name or folder path is too long to send. Shorten it or zip it first.Both named only a folder path and said to zip deeply nested folders. floe sendnow reports at once a receiver that stops the transfer whilefloe sendis waiting for it to take in more data. A receiver that stops without closing the connection, as a browser does, was reported only once it took in more data, which could take a minute or more. If it took in nothing, the send ended after a minute withbackpressure stall: peer not drainingin its place.- On Windows 10,
floe receivesaves a file whose name begins with a reserved device name and a dot, such asaux.horcon.txt, with an underscore in front (_aux.h). Windows 10 opens such a name as the device, so the receive stopped at that file. Windows 11 and other systems keep the name as sent. - Release builds of
floefor macOS now need macOS 13 Ventura or later. They are built with Go 1.27, which no longer supports macOS 12. On macOS 12, stay on 1.11.1 or follow Build from source with Go 1.26. - Web app: a browser that receives now tells the sender once it holds every file, as
floe receiveand Floe Desktop do.floe send1.11.0 or later and Floe Desktop 0.3.0 or later wait for that word. A file the page could not keep after the last byte, such as one the browser ran out of memory for, now ends the send as a failure with the reason instead ofSent. A tab closed before the word arrives ends it as unconfirmed. When every file matched,floe sendshowsVerified SHA-256 matched, Floe Desktop its green check mark, and a browser that sends to another browser “SHA-256 matched”. - Web app: a file sent without a SHA-256 now reaches the list only after the browser has read back what it holds of it, as a file with one already did. A file the browser could not keep used to appear in the list first and stop the transfer after.
- Web app: when the web app is updated while a transfer runs, the page no longer reloads in the middle of it. The tab keeps the version it loaded until the send ends, or until the receive is over and every file that arrived has been saved, and on a request link’s page until the drop ends; the next part it needs after that reloads it. A tab that was never clicked got no question first and lost its transfer.
- Web app: a link from
floeor Floe Desktop opened in a tab that is receiving from another such link no longer reloads a tab nobody has clicked at once, which dropped the files not yet saved there: it opens once the receive is over and every file that arrived has been saved, and in a tab that is sending, once the send ends. A tab you have clicked on still asks first, as before. - Web app: after a link such as Download or How It Works was clicked while the transfer page was still loading, and Back returned to the page, Forward could leave it with no question while a link was out or a received file was unsaved. The links in the header, the footer and the page itself now always load their page in full, so Forward asks.
- Web app: the line at the foot of the transfer card now reads “Keep this tab open and in front”, because Chrome and Edge can unload a tab in the background to save memory, which ends a send and loses the files a receiving tab holds.
- Web app: Download ZIP reads each file a piece at a time and writes the archive as it goes, so zipping a large transfer no longer runs the tab out of memory. Files go into the archive without compression. An archive of 4 GB or more, or of more than 65,534 files, is refused with
ZIP creation failed. Try "Download All" instead.before any file is read. An archive of more than 65,535 files used to be saved with no message, and unzip tools found few or none of its files. - Web app: in a ZIP, a name that differs from an earlier one only in letter case, such as
a.txtafterA.txt, is now numbered (a (1).txt), so unpacking on Windows or macOS keeps both. Before, those systems kept only one of them. - Web app: a ZIP that holds two files with the same dotfile name, such as two
.envfiles, now names the second.env (1), asfloeand Floe Desktop do. It was named(1).env. - Web app: the request link page now says “A file name or folder path is too long to send. Shorten it or zip it first.” for a pick it cannot describe, and “A file name or folder path is too long for their computer”, then “Shorten it or zip it first.”, when their Floe cannot save one. It named only a folder path and said to zip deeply nested folders, even for one file with a long name.
- Web app: the file lists no longer redraw every row at each step of a transfer, so a transfer of thousands of files no longer slows down as it goes.
- Web app: an error report the page cannot clean of the room link is now dropped instead of sent.
- Web app: the privacy page now says that a request link’s two counts stay in a tab the browser discarded until that tab loads again or you close it, and describes the small file Floe Desktop 0.3.2 keeps while a request-link drop arrives.
- Self-hosting: the published images are rebuilt as
1.11.2, with every web app change above. The client image moves Next.js to 16.4.1, past three advisories that do not reach Floe’s image, and the server image moves to Express 5.3.0 and dotenv 18. If you pinnedFLOE_IMAGE_TAG=1.11.1, move to1.11.2. - Self-hosting: the server now caps how many connections one address holds open at once, 60 by default, set with the new optional
MAX_SOCKETS_PER_IP. A connection past the cap is refused withRate limit exceeded, as one past the limit on new connections is, so the web app,floeand Floe Desktop each show what they already show for that limit. Compose,.env.docker.exampleand the Unraid server template carry it; adocker-compose.ymlfrom 1.11.1 or earlier does not pass it.
Floe Desktop checks a pasted link against your server before it connects, says more exactly what went wrong, and the portable build adds no File Explorer entry until you ask
- A link pasted into Receive is checked against the server in Settings before anything connects. A floe.one link while another server is set, and a link from another Floe server while none is, each stop with a line that says what to change in Settings.
- A linked file inside a folder you send is sent at the size of the file it points to, and a link to a folder, or one that points nowhere, stops the send before it connects.
- A pasted room link whose room id was cut short shows “That link is incomplete” without contacting the server.
- A room link pasted into Receive with other text in front of it, such as
Link:, now stops before anything connects with “That code wasn’t recognized”. Paste the link on its own. - The portable build no longer adds Send with Floe to File Explorer on its first run (turn on Show in right-click menu in Settings), and no copy of Floe takes over another copy’s entry. The installer build still adds it on its first run, and again after a reinstall unless you switched it off. An entry left by a copy whose folder is gone is taken over by a copy that would add one and removed otherwise, so File Explorer keeps no Send with Floe that cannot start.
- A request for more than 2 GB over a relayed connection now warns “This 3.1 GB drop is over the 2 GB relay limit”. It said “the 2 GB Hide my IP limit” even when Hide my IP was off.
- A request-link drop that stops at the 2 GB relay limit after some files arrived now says how many were saved, for example “Over the 2 GB relay limit · 2 of 5 files saved”, and offers Show in folder. It said “Nothing saved” with no way to the folder, and its History row said the drop stopped before any file.
- An open request link now says why a sender could not connect when Hide my IP is on and the server has no relay, or its relay details could not be read: “The sender couldn’t connect: Hide my IP is on and no relay is available”. It showed only “Waiting for files”.
- Test in Settings now tells the two proxy faults apart when the realtime connection is refused: an answer of 403 reads “(check that your proxy passes the original Host header)”, a 404 reads “(check that your proxy forwards /ws)”, and any other refusal names both, “check that your proxy forwards /ws and passes the original Host header”. It named only /ws.
- Test in Settings says “The server is limiting requests from this network. Wait a minute and test again” when the server’s own rate limit answers. It blamed the proxy with “The API answered HTTP 429 (check that your proxy forwards /api/)”.
- Test in Settings on a server with no relay now says “Connected, but this server has no relay: Hide my IP will not work, and some networks will not connect”. The old line mentioned only Hide my IP.
- A code lookup the server is limiting now reads “The server is limiting requests from this network. Wait a minute and try again”, and a lookup the server could not answer (a proxy error, for example) reads “Can’t reach the server”. Both read “That code wasn’t recognized”, which sent people back to recheck a code that was right.
- A receive whose sender has left says “this code or link is no longer active; ask the sender for a new one”. It said “this code” even when you had pasted a link.
- A transfer whose connection to the server drops before it starts now says “Can’t reach the server”. A send that was waiting for its receiver said “The receiver left before it started”, although nobody had arrived, and a send or receive still waiting for the server said “The connection dropped before the transfer finished”.
- Keyboard shortcuts wait while a dialog is open.
Ctrl+Entercould start a transfer behind Close Floe?, andCtrl+O,Ctrl+V,Ctrl+HandCtrl+,could change the screen behind a dialog or close Reset all settings? unanswered.Ctrl+Zno longer spends an undo behind Close Floe?. - While a receive runs, the Send tab hides its drop area and its Files and Folder buttons, as it does during a send. The buttons used to add files while a drop or a paste onto the same area was ignored. Files you added before the receive stay.
- The left rail reads “Direct, no size limit from Floe” and says a receiving browser can only hold so much. It read “Direct & unlimited” with “no size cap”.
- A peer connection that cannot be made says
failed to create peer connectiononce instead of twice. - A second received file named like
.envis saved as.env (1), not(1).env. - A Server address typed with capitals, with
:443or with a dot at the end of the host name gives share links at floe.one when it names floe.one’s server, and the empty Share link address field in Settings shows that address. - Start over now asks first when a send that is still connecting or waiting for its receiver carries a note that has not been delivered (“Starting over clears your unsent text”). With nothing to lose it still starts over at once.
- The installer build’s uninstaller removes only the files it installed, and the install folder only when nothing else is left in it, so other files in a folder you chose for Floe are kept.
- A
desktop.jsonthat cannot be read is kept beside it asdesktop.json.badbefore Floe writes its defaults, so settings from a broken hand edit can be copied back. - A connection the server turns away by its limit on new connections from one network now says “The server is limiting connections from this network. Wait a minute and try again”.
- Clicking Send with only empty folders chosen now says “The folders you chose have no files to send”.
- A request link pasted into Receive without
https://, or inside quotes or angle brackets, keeps its Open in browser button. - When the receiver stops an ordinary send, the line reads “They stopped the transfer” where it said “transfer failed: They stopped this drop”, and the receiver’s other reasons show without “transfer failed:” in front.
- An error from the server that this version does not know now reads “the server answered with an error this version of Floe does not know”. It read “The server is busy, try again in a minute”, and a server’s words that held one of Floe’s own phrases were shown as they came.
- The temporary copy of a text note is removed when Floe quits during its send, and one left by an earlier run is removed at the next start.
- A file dropped on the window and files sent from File Explorer are ignored while Start over?, Close Floe? or Reset all settings? is open, as they are during a transfer, and
Ctrl+Rand the Floe button at the left of the title bar wait behind Close Floe? and Reset all settings?. - A connection that fails while the two devices are still connecting now reads “Couldn’t connect the two devices”, the line the other connecting failures already showed. It read “The connection dropped before the transfer finished”, as if a transfer had started.
- A receive of only empty files no longer posts a byte count of 0 to the global stats counter, which the server always refused.
- The transfer protocol version is unchanged, so this still sends to and receives from older CLI, desktop, and browser peers.
floe receive tells the sender when you decline, floe send tells the receiver when you press Ctrl+C, and a pasted link is checked against your server before anything connects- A no at the
Accept? [Y/n]prompt offloe receivenow reaches the sender. The receiving side closed the connection without a word, sofloe sendended withconnection closed while waiting for the receiver (transfer declined or receiver exited)and could not tell a person who declined from a terminal that was closed. Nowfloe sendprintsError: They declined. Nothing was sent., Floe Desktop shows the same sentence, and a sending page in the browser reads “Transfer failed” with “receiver declined the transfer”. The earlier line still appears when the receiving side quits without answering. - Pressing
Ctrl+Cinfloe sendnow tells the receiver and closes the connection.floe receiveends at once withThe sender stopped., and a receiving browser shows the same sentence. Before,floe sendexited without a word, sofloe receivewaited a minute and reported a stalled transfer, and a browser waited until its connection failed. floe receivenow checks a pasted room link against the server it is set to use in both directions. A link from another Floe server, with no--serverorFLOE_SERVERset, stops before any network call withThat link is for another Floe server, but this Floe is set to use floe.one. Use --server with that server's address, then try again.- A linked file inside a folder you send with
floe sendis sent at the size of the file it points to. A link to a folder, or one that points nowhere, stops the send before it connects, with a line that names it. floe receivenotices a sender that leaves while the prompt is waiting. An answer typed after the sender had gone started the transfer anyway and ended withconnection closed mid-transfer, as if something had gone wrong on the way. It now ends withError: the sender left before the transfer was acceptedand creates nothing in the folder.curl -fsSL https://floe.one/install.sh | shchecks the archive it downloads against the release’schecksums.txtwithsha256sumorshasum. On a machine with neither tool it printedWarning: no sha256 tool found, skipping checksum verification.and thenChecksum verified.anyway. It now printsChecksum verified.only when one of the two tools compared the SHA-256. With neither, the warning stands alone and the install goes on, as before. The script is served from floe.one, so the fix is already live and needs nofloeupdate.- The
Timerow of theSentandReceivedboxes counts from the moment the receiver accepted. Both clocks used to start before the answer, so the time a person spent at the prompt was added to the transfer, and the average speed beside it came out lower than the files really moved. - A server that refuses the connection is reported with its answer: the error from
floe sendandfloe receivenow carries the HTTP status, as inwebsocket: bad handshake (HTTP 403), where the line stopped atbad handshakewhatever the server had said.403is the server’s own check on where a request comes from, which a reverse proxy that does not pass theHostheader through trips;404is a reverse proxy that does not forward/ws. floe receive -o <dir>no longer leaves an empty folder behind when the receive cannot start, when you answern, or when the sender never sends. The folder is made when the first file is saved. A folder that cannot be made is still reported before the code is used, so the same code can be tried again.floe updateon a build compiled from source now exits with status 1 and printsError: Cannot update a dev build.It printed the sentence and exited with status 0, which a script could not tell from an update that ran.floe updatenow recognizes a Homebrew install in Homebrew’s default folder on an Intel Mac (/usr/local) and points you tobrew upgrade floe. It missed that install and replaced the file Homebrew manages.- The update hint in
floe versionnow readsUpdate available: 1.12.0 run `floe update`, or your package manager's upgrade command. It named onlyfloe update, which refuses on a Homebrew, Scoop or Winget install. floe updateand the hint infloe versionnow name a release without the leadingv, as the rest of their output does:Update available: 1.10.11 -> 1.11.0,Updated to 1.11.0. They mixed1.10.11andv1.11.0.- A code the server does not know now reads
code "olive-tiger-castle" not found: it was already used, the sender left, or it expired (a code lasts 10 minutes at most). The old line named only the 10 minutes, the least likely cause. floe receiveinto a room whose sender has left now saysthis code or link is no longer active; ask the sender for a new one. It saidthis code, also for a pasted link.- A
floe sendthat loses its own connection to the server while it waits for a receiver now saysthe connection to the server was lost before the peer connected, and one whose receiver left saysthe other side left before the connection was established. Both saidpeer disconnected before connecting, which blamed the other person even when the connection that failed was the sender’s own. floe send --tonow ends a relayed drop over 2 GB that saved nothing withNothing was sent. Send 2 GB or less.It saidSend under 2 GB, and a drop of exactly 2 GB is allowed.- The macOS and Linux install script creates
/usr/local/binwhen it is missing, installs to~/.local/binwhensudocannot be used, and on an unsupported processor points atgo installor a source build. When~/.local/binis not on yourPATH, its note names the file your login shell reads (~/.zprofilefor zsh,~/.bash_profilefor bash when you have one,~/.profileotherwise), where it always said~/.profile, which zsh never reads. And when it installs to~/.local/binwhile an earlierfloeis still in/usr/local/bin, it says so and gives the command that removes the old one. - Pressing
Ctrl+Cinfloe receiveafter the transfer has finished, while it waits for the sender to read its confirmation, no longer printsCanceled.or exits with status 130. It stops waiting at once, exits with status 0 and reports its byte count unless you opted out. ACtrl+Cbefore then still cancels, as before. - A peer connection that cannot be made now says
failed to create peer connectiononce infloe sendandfloe receive, where it said it twice. floe receivestops before any network call on a room link whose room id was cut short or mistyped, and on a room id or room link it cannot read (a room id pasted on its own, or a link percent-encoded whole or inside a mail-safety redirector), withThis link looks incomplete. Copy the whole link again, including everything after the # sign. Put the link in quotes.A cut-short link used to reach the server and end withserver error: Invalid room ID, and the others were printed back in the error line, room id and all.- Something typed where a code goes that is not shaped like one, such as words joined by underscores or spaces, now reads
code not recognized: a code is words joined by hyphens, like olive-tiger-castleinstead ofinvalid URL. floe <link>withreceiveleft out no longer prints the room link back. It printsThat looks like a link to receive from. To receive, use: floe receive <link>.- When the server’s relay details cannot be read,
floe sendandfloe receivenow warnWarning: could not read TURN credentials from the signaling server. Using STUN only.instead of carrying on in silence. - The
Accept? [Y/n]prompt offloe receivenow ends its own line when stdin is closed and there is no answer to read. It shared a line with the first progress line. - On Windows,
floe updatenow moves the oldfloe.exeaside asfloe.exe.floe-update-old, and the next start offloeremoves it. It wasfloe.exe.bak, which stayed until the next update. The cleanup at start never touches afloe.exe.bak, butfloe updatestill deletes one before it renames, as it always has. - A second received file named like
.envis saved as.env (1), not(1).env. --serverandFLOE_SERVERare read in any letter case, with or without the default port and with or without a dot at the end of the host name, sohttps://API.floe.one,https://api.floe.one:443andhttps://api.floe.one.print share links at floe.one instead of at the API host.- A transfer of only empty files no longer posts a byte count of 0, which the server always refused.
- With one file left, the lost-connection line of
floe send --toendsAsk them for a new link to send the other one. - A
/wsconnection the server or a proxy refuses with 403 or 404 now adds one sentence to thefloe sendandfloe receiveerror naming the likely cause: a reverse proxy that changes the Host header, or one that does not forward/ws. - Web app: three sentences on the transfer page were corrected. The Direct badge’s tooltip says “No server carries them. Floe sets no size limit, but a receiving browser can only hold so much.” where it said “No servers involved. Unlimited speed and size.” The line under the drop area reads “No size limit from Floe over direct connections”. The hint under Network relay fallback begins “Files go through it only when a direct connection isn’t possible”.
- Web app: opening a page no longer sends Sentry a session record. The error-monitoring library sent one for every page by default (a random session id, the time, the site’s build version and your browser’s user agent, with no page address), and Floe never used them. The site’s server sent Sentry a count of the requests it handled each minute, with no address and no user agent, and that has stopped too. Error reports and the 10% sample of performance traces are sent as before. In those, the address of the page that referred you now has a room link removed from it, as the page address already had. Only a link in the old
?room=form could put one there. - Web app: Sentry is sent less. Each time a tab was hidden, the error-monitoring library also posted a count of the errors, traces and background requests it did not report, with a reason and the time, so Sentry heard from nearly every visit and not only from an error or the 10% of page loads that are traced. The site’s server posted a count of its own about once a minute while it was running. Both have stopped. A traced page load also carried the device’s approximate memory, its processor count, the network type the browser reports, its round-trip estimate and the HTTP version each request used, and the polling requests a page makes while it connects to the Floe server were recorded with that connection’s id in their address. None of these is sent now. The page also timed clicks and key presses and sent each timing as a record of its own. Sentry’s servers kept the IP address those records arrived from, which they do not do for an error report or a page-load trace, so those timings are off. Sentry’s servers also worked out a location down to city from the IP address a report arrived from and stored it with the report, though no line of Floe’s code sent one. Each report from the browser now leaves with an empty location field, which keeps Sentry from working one out. Reports stored before this keep theirs until Sentry’s retention period removes them. Security and privacy lists what is still sent.
- Web app: a receive that ends early no longer looks finished. When the connection ended after some files had arrived and before the rest, the receiving page kept its green check and a count such as “1 file received”, and the progress row of the file that never finished stayed on screen. It now reads “Received 1 of 3 files. The transfer ended before the rest arrived.” in amber, with no check and no progress row, and the check appears only once every file the sender announced has arrived. Between files, the same place reads “Received 1 of 3 files. Waiting for the rest”.
- Web app: two waits that never ended now end. A browser sender whose connection to the server dropped while the two devices were still connecting came back behind its own receiver, so neither page was told to start and both waited for good. The receiving page now steps aside for a sender that returns, and the transfer starts. And a sending page whose re-join was refused, because its old connection still held its seat while a recipient had already arrived, kept showing a link nobody could reach. It now reads “Reconnecting to your link” and tries again for about a minute, then says “This link stopped working. Reload the page, add the files again, and share the new link.” if the room is still closed to it.
- Web app: a link nobody holds says so. A receiving page that opened a link whose sender had left stayed on “Waiting for the sender to start” for as long as it was open. It now reads “The sender is not connected”, with “Keep this page open if they are coming back. Otherwise ask them for a new link.” under it. A second browser that opens the same link still shows the old line, because the server tells it someone is in the room. The Link Invalid card’s sentence now names what really shows it: “This link is incomplete, already in use, or locked to the networks that first used it.”
- Web app: six messages about the relay no longer ask for something the page cannot do. Two told you to enable “Network Relay”. The sending page’s checkbox is Network relay fallback, and it is gone once a link exists, so a sender who unchecked it now reads “Connection failed. This link was made with Network relay fallback off. Reload the page, add the files again, leave it on, and share the new link.”, and a receiver reads “Connection failed. Ask the sender to try again. If they turned the relay off, ask them to leave it on.” Four said to remove files where a file cannot be taken out of the list. They name the size now, since one file can be over the cap by itself: the notice for a relayed transfer over 2 GB says “Reload the page to send 2 GB or less”, the receiving page is told “Ask the sender to send 2 GB or less”, and on a request link’s page the two lines read “Turn off Hide my IP, or send 2 GB or less.” and “Send 2 GB or less, or try another network.”
- Web app: the first row of the received files list is no longer cut off at the top. The tooltip that carries each file’s full name counted toward the list’s height while it was hidden, so a list that fit still scrolled 23 px after a file arrived, and the sending and receiving lists both drew a scrollbar beside a single row.
- Web app: the receiving page no longer says “Keep this tab open. Closing it interrupts the download.” where nothing is downloading: under the Link Invalid card, and while it reads “The sender is not connected”.
- Web app: the “Too many refreshes. Reconnecting” banner goes away once the page is connected again. When too many connections come from one address, the server refuses the next one and the page retries by itself. The banner stayed on screen after a retry had worked, on a page whose badge already read Ready, until you closed it. A page that had opened an incomplete link lost its Link Invalid card to that banner, and to any reconnect after its connection to the server dropped, and then read “Secure room joined” over a room it had never joined. It now keeps the card.
- Web app: a finished send no longer goes back to looking unfinished. When the status changed from “All Files Sent!” to “Transfer complete” or “Connection interrupted”, the last file’s check mark turned back into a spinner and the row under the bar read “Sending file 3 of 3…” at 100%. That followed a send to
floe receive, which exits as soon as it has the files. The rows now keep their check marks and the row under the bar keeps “Sent 3 files”. Once the page reports a send as failed or interrupted, the file that was moving stops spinning, and the status line no longer spins beside “Connection interrupted”. When a recipient opens the link again, the rows start clear. - Web app: a send that did not go through no longer ends on “Transfer complete”. Two cases did. When the other side refused a file after the last byte for any reason other than a mismatch, because it could not save the file for example, the status read “Transfer failed” under the reason and then turned into a green “Transfer complete” as soon as the other side left or the page lost its connection to the server. It now stays on “Transfer failed”. And once one send had finished, a second recipient who opened the same link, stopped partway through a file and left the room also ended on “Transfer complete”. That now ends the way it does for a first recipient: on “Connection interrupted”, or on “Peer disconnected. Waiting for reconnection” when the page hears they left the room after the connection has closed.
- Web app: the notice on a request link opened inside another app’s browser now says where the page works. The sentence under the Open in your browser heading ended “Open Floe in Chrome or Safari for the best experience.” on every page, and a request link’s page is supported in current Chrome and Edge on a computer. On a request link that sentence now ends “Open the link in current Chrome or Edge on a computer.” The steps under it, and the card on a share link, are unchanged.
- Web app: a connection error now says what to do, in Floe’s own words. When the connection failed in a way the page had no wording for, it showed “Connection error:” followed by the browser’s technical message. Part of that message could come from the other device, so whoever held the link could put a sentence of their choosing in the red banner, on the sending page and on the receiving page, and the same text went to Sentry. The receiving page now says “Connection failed. Reload the page to try again. If it fails again, ask the sender for a new link.”, the sending page says “Connection failed. Ask the other device to open the link again. If it fails again, reload the page, add the files again, and share the new link.”, and Sentry is sent a fixed error code with no text.
- Web app: the Link Invalid card shows only for a link that is invalid. The page decided to show it by looking for the words “Link Expired” in its error message, and the other device’s words can be that message: a sender that stopped a transfer with a reason spelling those words switched a connected receiving page to the card, on a link that was good. The card now answers to Floe’s own value alone, and such a reason shows as “The sender stopped the transfer.”
- Web app: a sending page no longer waits for good on a reply it cannot read. The receiving side answers each file with the position to resume from. When that answer was not a number at all, the sending page failed while it worded its refusal and stayed on its last status line with no message. It now says the receiver asked to resume from “a position that is not a number, which is not possible. Please try again.” A version number that was not a number did the same on either page, to a refusal as well as to a reply, and now reads as a version mismatch. Any other failure in the page’s own sending code used to show nothing as well, and now reads “Something went wrong while sending, so the transfer was stopped. Reload the page, add the files again, and share the new link.” Separately, the file count a finished receive sends to analytics is now the number of files that arrived. It was the total the sender announced, which a sender could set to any number.
- Web app: the check mark beside the share link no longer depends on your file’s name. While a file is being sent the status line reads “Sending:” followed by its name, and the page showed the green check whenever that line contained the words “Transfer complete”, so a file called
Transfer complete.txtgot the check while it was still on its way. The check now appears only when the status is “All Files Sent!” or “Transfer complete”. - Web app: the Link Invalid card shows a broken link in its red circle. It showed a shield with a check mark, the mark for something safe, on the one card that says a link cannot be used.
- Web app: on a request link opened inside another app’s browser, the box of steps is now titled “To use this phone instead”. The sentence above it says to open the link in current Chrome or Edge on a computer, and the steps open the phone’s own browser, so under the old title, “How to open in your browser”, they read as the way to do what the sentence had just asked. The steps themselves are unchanged, and so is the card on a share link.
- Web app: when the other side stops a relayed drop over 2 GB before any file is saved, a request link’s page now ends “Nothing was sent. Send 2 GB or less.” It said “Send under 2 GB”, and a drop of exactly 2 GB is allowed.
floe send --tosays the same from this release on. - Web app: two sentences of the privacy page now say what the code does. The page said Umami “does not collect personally identifiable information” beside a list that names the country, region and city Umami works out from your IP address. It now says what can be checked: Umami does not keep the address. And the page said the connection type, the relay setting, the transfer’s progress, the file count and the total size go to Sentry “at the time of an error”. A performance trace in the 10% sample carries the same facts when a transfer began on that page, so the page now names both. Nothing about what is collected changed.
- Web app: a request link’s page no longer says the server has no relay when it only failed to ask. With Hide my IP on, the page asks the server for its relay list before it connects. When that request failed, or the server was limiting requests from your network, the page said “This Floe server has no relay right now. Turn off Hide my IP to send directly.” It now says “Couldn’t check for a relay. Try again, or turn off Hide my IP to send directly.”, and Send asks the server again. The first line now shows only when the server answered and its list has no relay in it.
- Web app: a browser that is receiving now tells the sender when it cannot read a file’s description. The description carries the file’s relative path, and one longer than 1,000 bytes, which takes a path of about 800 bytes, was refused without a word to the other side: the receiving page showed its own error, and a
floe sendon the other end waited 120 seconds and ended withtimed out waiting for ack. The page now answers at once, asfloe receivedoes, andfloe sendstops with “A folder path is too long for their computer. Zip deeply nested folders first.” - Web app: two more things are kept out of Sentry. When the receiving page fails on a fault of its own, the report it sends now carries fixed words, the kind of error and where in Floe’s code it happened. It used to carry the browser’s own error message, and a browser may quote the data it was handling in one. No case of that is known. And reports from the site’s own server now leave with an empty location field, as reports from the browser already do. Sentry worked a location out from the address a report arrived from, which for the server is the hosting provider’s data center, so it never named a visitor. With both sides empty, no report in the project holds a location.
- Web app: on a self-hosted server, Report this link on a request link’s page no longer writes to Floe’s maintainers, who cannot act on another server’s links. It starts an email to the address the server’s operator sets in the new
REQUEST_REPORT_EMAILvariable, and a server with no address set shows no Report this link at all. If you self-host with request links on, setREQUEST_REPORT_EMAILto one address you read, or the link is gone once you update. Under Docker Compose, download the currentdocker-compose.ymlfirst, which passes the variable to the web client; on Unraid, fill in the Floe-Client template’s Request Link Report Email field. See Configuration. On floe.one nothing changes. - Web app: five small things on the transfer page now match what is happening. “Transfer blocked. Relay limit exceeded.” no longer has a spinner beside it, since the page has already closed that connection. “SHA-256 matched” stays under a finished send when its status changes to “Connection interrupted”; it used to disappear while the rows above still read sent. After a receive that ended with nothing, the receiving card no longer draws its three joining steps again with a spinner, and no longer says “Keep this tab open. Closing it interrupts the download.”: nothing is in progress, and the banner says what happened. On an iPhone or iPad, the tip to use “Download ZIP” shows only when that button is there, on a transfer of two or more files. And a transfer made only of empty files no longer sends the public counter a report of 0 bytes, which the server refused.
- Web app: a sending page that stops by itself (a file it can no longer read, a receiver that did not answer for 2 minutes, or an internal error) now tells the receiving side why and closes the connection, instead of leaving it waiting.
- Web app: a sending page made with Network relay fallback off that turns down a relayed connection now tells the receiving side why, instead of a bare close that asked them to start the transfer again.
- Web app: a receiving page that already has every file stays complete when the sender stops just after the last one, instead of reading “The sender stopped.”
- Web app: the page reads its relay details again before a connection when its first read failed or they are an hour old, so a page left open for a day, or one that loaded while the server was unreachable, can still use the relay.
- Web app: the in-app browser card shows the link itself, and says so when Copy cannot reach the clipboard.
- Web app: a folder dropped on the Send page is refused at the drop with a message, instead of failing partway through the transfer.
- Web app: the transfer page asks before you close or reload it while that would cost you something: a sending page from the moment it makes a link until the send ends, and a receiving page while a receive is under way or a file that arrived has not been saved yet (its own download button, Download All and Download ZIP each count as saving it). The Floe button, the page’s own links, Back and Forward ask too; Back and Forward did not after you had moved between floe.one pages in the same tab. A page that has already told you to reload does not ask, and a file dropped outside the drop area no longer opens in the tab.
- Web app: a receiving page whose own connection to the server blipped no longer shows “Link Invalid” at once; it tries again for about a minute while its old place in the room is freed.
- Web app: the status line under the share link wraps on phones instead of cutting off “Peer disconnected. Waiting for reconnection” and “Transfer blocked. Relay limit exceeded.”
- Web app: the full-page error screen is dark, in the site’s own design, with a Reload page button.
- Web app: on a request link’s page, the Arrived line names the route only when the page could read it, for example “1.2 GB in 3m 10s.”; “Request links are turned off right now” and “Request links are not available on this Floe server.” now have a Try again button that keeps your files; and one file left of several reads “send the other one”.
- Web app: on a receiving page, “Keep this tab open. Closing it interrupts the download.” now shows exactly while the page would ask before it is left. Once every file has arrived and been saved, the line under the card reads “End-to-end encrypted. Files are never stored on a server.” again; it used to stay amber for as long as any file was listed.
- Web app: the privacy policy now lists the short trail Sentry error reports carry, and says the GitHub installer of Floe Desktop downloads WebView2 during setup.
- Web app: the privacy policy says that while a room is open the server keeps a keyed hash of each device’s network address, never the address itself, and the terms say that Floe does not scan files for malware and that request links are in Beta and can be turned off for everyone.
- Web app: the home page, the FAQ, the download page and the page-not-found screen now say what the apps do: a share link and its QR code come after Create secure link, the list of what the server handles names the
Origincheck it logs, and the Windows download line names the processors the app is built for instead of saying it requires them. The privacy policy names both Google STUN servers, says an update check that fails is tried again at the next start or run, lists the notification entries the GitHub build of Floe Desktop writes, links the full list of what the app keeps on your PC, and splits its longest sentences; the terms say in plain words what indemnify means. - Self-hosting: a
MAX_*limit set to a negative number made the server refuse everything that limit guards, with nothing in the log. A value that is not a whole number of at least 1 (a negative number,0, a word, or a spelling such as1e3) now falls back to the default, and the server logs one line that names the variable. - Self-hosting: a WebSocket request for any path other than
/wsand/socket.io/got no answer and was closed about a second later. It now gets404 Not Foundat once, so a proxy that forwards/ws/or a prefixed path shows up as a status instead of a silence. - Self-hosting: a server started without
TRUSTED_PROXY_COUNTnow logs one line at startup saying that the default of 1 is in use and to set it to the number of reverse proxies in front of the server.server/.env.examplenow ships0, the right value for a server reached directly. - Self-hosting: the signaling server’s HSTS header covers its own host only. It also carried
includeSubDomains, which a server on a bare domain would push onto every other subdomain of that domain in each visitor’s browser. - Self-hosting: a new server variable,
TURN_TLS, set tooff(orfalse,0,no) leaves theturns:address (TLS on port 5349) out of the relay list a self-hosted coturn hands out, for a coturn that has no TLS certificate. Unset, the list is unchanged. Compose,.env.docker.exampleand the Unraid server template carry it. - Self-hosting: the transfer counter no longer loses a report that arrives in the moment after the server starts, before it has read the stored total.
- Self-hosting: with Docker Compose, changing
CLIENT_PORTorPORTon its own now works on one machine. The two addresses built from those ports follow them, where before the page loaded and never connected until you also setCLIENT_URLorNEXT_PUBLIC_SOCKET_URL.docker-compose.ymlnow needs Docker Compose 2.8.0 or later, and an older Compose stops with an error instead of starting a stack that cannot connect. This applies to the file onmainat once. - Self-hosting: the Unraid Floe-Client template no longer ships a placeholder in Signaling Server URL, which an install that did not notice it ran with. The field is empty and its description says what to put there. If you added the container from the earlier template, clear the field’s Default Value as well.
- Self-hosting: the Unraid Floe-Server template has a Request Link Policy Folder field, so turning request links on no longer means adding a Path by hand.
- Self-hosting: a self-hosted web app sends
/docsto floe.one/docs instead of serving it through a proxy, the client image warms its own picture cache when it starts, andclient/.env.exampleturns off Next.js telemetry. - Self-hosting: with request links turned off, Keep waiting on a declined request link now ends the link with “Request links are off on this server” instead of leaving it on “Waiting for files”, where no sender could reach it.
- Self-hosting: the published images are rebuilt as
1.11.1. Run the client and server images at the same version, and if you pinnedFLOE_IMAGE_TAG=1.11.0, move to1.11.1. - The transfer protocol version is unchanged, so this still sends to and receives from older CLI, desktop, and browser peers.
Request links (Beta): make a one-time link in Floe Desktop, the person you send it to sends files from their browser, and nothing is saved until you accept, unless you turn on Auto-accept for that link
- Request link sits next to Code under Receive, marked Beta, with no switch to turn on. It needs a Floe server that offers request links, and floe.one does.
- One person, one use. A link ends when the time you pick under Link ends runs out, from 30 minutes to 7 days (24 hours by default), or when you close it, and it works only while Floe Desktop is open and your PC is awake and online.
- Each drop lands in a new folder under
Downloads\Floeunless you choose another. A relative folder you type is read from your home folder, and one Floe cannot use is refused at Make link with “Couldn’t use that folder”, so no link is made. File types that File Explorer opens by itself arrive renamed with a.floe-blockedending, and files are not scanned. - Auto-accept, a check under Link ends, lets one link save drops without asking. It is off on every new link and never remembered. A drop still asks when something about it is unusual, such as low space, a drive that cannot keep Windows’ downloaded-file mark (FAT32 and exFAT drives, like most USB sticks, and many network shares), a drive Floe cannot read, or a drop that would leave less than 20 GB or a tenth of the drive free, and the request says why. History marks a drop it took “Accepted automatically”.
- A finished drop lists the files that arrived, each with its size: the first 200 in the order they were saved, then a count of the rest.
- Every file you receive is checked against a SHA-256 the sender computed, when the sender provides one. A file that does not match is deleted and the transfer says why. Floe Desktop now sends a SHA-256 with every file it sends.
- A finished transfer shows a green check mark when every file’s SHA-256 matched. It shows on the finished card, in History for a request-link drop, and after a send or receive by code. Without it, not every file could be checked: a send or receive by code then shows a gray check mark, where 0.2.12 showed a green one every time, and a request-link drop shows none. The green check mark means the files arrived intact, not that they are safe.
- Settings has a new Notifications section: turn Windows notifications off, or keep them and turn off the sound. Floe sends none while its window is in front and you are using the PC. With notifications off, a request still flashes the taskbar button and puts
(1) Floein the title. Open goes to Windows’ own notification settings, where Windows decides where banners appear. - The Microsoft Store version now shows its notifications under its own name. Before, Windows could drop them without a word, because they went out under a name only the downloaded version of the app registers.
- Every transfer you receive, not only request links, now refuses a file whose path is absolute, nested too deep or too long, or that is larger than the save drive can hold (4 GB or more on a FAT or FAT32 drive), before any of that file is saved, and the sender is told why.
- When the other side leaves while a transfer is still connecting, Floe Desktop says so right away instead of waiting 30 seconds. A browser that loses its connection to the Floe server for a moment while connecting counts as leaving, so start the transfer again.
- While a connection is being set up, the other side of a transfer can no longer make Floe Desktop hold more and more memory: the connection candidates and the unread data it can send now have limits that no real Floe peer reaches, and a second data channel, which no Floe peer opens, ends the connection. Floe Desktop 0.2.12 and earlier limit none of these, apart from holding at most 256 unread frames of any size.
- A send to a
floeCLI or Floe Desktop from this release now ends only when the receiving side says it saved every file, so a file it deletes or cannot save at the last moment, such as one whose SHA-256 did not match, is reported instead of shown as sent. If the connection is lost before that answer, Floe Desktop says “The connection dropped before the transfer finished”. A send to a browser or an older receiver ends as before. - Quitting Floe Desktop while it is receiving no longer hangs when closing a partly received file stalls: it gives up on that file after 5 seconds and quits, and the file keeps its
.partending, so it never looks finished. - If a request link drop stops after it was accepted, the files it already saved count toward global stats when Contribute to global stats is on.
- Limits: relayed drops stop at 2 GB, there is no resume, the person sending uses current Chrome or Edge on a computer, or
floe send --to, during the Beta, and they see your IP address once they connect, even if you decline, unless Hide my IP is on. - The transfer protocol version is unchanged, so this still sends to and receives from older CLI, desktop, and browser peers.
floe.one opens request links made in Floe Desktop, so the person who got a link can send files and folders straight to that computer
- The request link page (floe.one/r/…) connects only when you click Send, sends straight to the other computer, shows only fixed messages, and has its own Hide my IP switch (relay only, 2 GB per drop). A link closed, or past its end time, before anyone used it says “This link has ended”.
- Files you send now carry a SHA-256, and a file you receive is checked against one when the sender provides it, and discarded if it does not match. When the SHA-256 takes too long, at most 45 seconds after a file’s last byte when sending, or 90 seconds when receiving with more files to come, the file goes through unchecked instead of failing the transfer.
- A sender stops within seconds when the receiving side refuses, a transfer that is already connected keeps going when the other side’s connection to the Floe server drops for a moment, a page turned away for too many connections tries again on its own, and share links and request links are no longer kept in the browser’s offline cache.
- A browser tab that runs out of memory while receiving now stops the transfer once, says that the browser ran out of memory and that Floe Desktop or the CLI save large files straight to disk, and lets go of the file data it held. Before, it failed again on every piece that arrived and kept everything it already held. The sender is told:
floe sendstops and prints the reason, and a browser sender says the connection closed before the transfer finished instead of staying on its sending screen. A transfer whose connection drops partway now lets go of its partial file too. - In Chrome, Edge and other Chromium browsers, a tab receiving a file now holds no more than about 16 MB of it at a time. The browser keeps about 2 GB of what has arrived in memory on a computer and moves the rest into its own temporary files on disk, which it deletes when the page closes, so a large file no longer has to fit in the tab. If that storage fills up, the transfer stops while it is running instead of failing at the download. In a private window nothing goes to disk, so files share about 2 GB on a computer, and Firefox, Safari and every iPhone and iPad browser still hold each file in memory. The privacy page now mentions those temporary files.
- CLI:
floe send <paths> --to <request link>sends through a request link made in Floe Desktop. It waits until the drop is accepted, prints only fixed messages, as the page does, and exits 0 only after their Floe confirms every file arrived. A link closed, or past its end time, before anyone used it printsThis link has ended. Ask them for a new link.A link made on floe.one is refused before Floe contacts any server while--serverorFLOE_SERVERnames another server. - CLI: a request link given to
floe sendwhere a file goes, without--to, or typed as the command itself (floe <link>), is refused with one line that shows how to use--to, and the link is not printed back. - CLI:
floe receivechecks each file’s SHA-256 when the sender provides one and deletes a file that does not match,floe sendsends a SHA-256 with every file, and both showVerified SHA-256 matchedwhen every file matched. - CLI:
floe receiverefuses a file whose path is absolute, nested too deep or too long, or, on Windows, that is larger than the save drive can hold (4 GB or more on a FAT or FAT32 drive), before any of that file is saved, and tells the sender why. - CLI: when the other side leaves while connecting,
floe sendandfloe receivestop right away withthe other side left before the connection was establishedinstead of waiting 30 seconds. A browser peer that loses its connection to the server for a moment while connecting counts as leaving. - CLI:
floe sendto afloe receiveor Floe Desktop from this release waits until the receiving side says it saved every file, so a file it deletes or cannot save at the last moment is reported instead of counted as sent, and a connection lost before that answer ends withthe connection closed before the receiver confirmed delivery. A send to a browser or an older receiver ends as before. - CLI:
Ctrl+Cduringfloe receiveno longer hangs when closing a partly received file stalls: after 5 seconds it exits anyway, and the file keeps its.partending. - CLI:
Ctrl+Cduringfloe receivetells the sender the transfer was stopped, andfloe sendfrom this release ends right away withError: They stopped the transfer. - CLI: a request link pasted into
floe receive, in any shape it can be pasted, is refused with one line that says it is for sending, and the link is not printed back. - CLI:
floe receivewith a floe.one link while--serverorFLOE_SERVERnames another server stops before any network call and says to unsetFLOE_SERVERor use--server https://api.floe.one, so the room never reaches the other server. - CLI: while a connection was being set up, the other side of a transfer could send a value that
floe sendandfloe receivelogged to the terminal exactly as it arrived, terminal control sequences included. A peer could use that to clear your screen, plant a clickable link, or, in terminals that allow it, write to your clipboard. Every CLI release since v1.1.0 has this, v1.10.11 included. These log lines now show every control or invisible formatting character as a visible escape such as\x1b, and the rest of each line reads as before. - CLI: the error printed when connection setup fails,
Error: WebRTC setup failed: ..., can quote part of the other side’s offer or answer, and it reached the terminal the same way. Every CLI release has this one, v1.0.0 through v1.10.11. It is now escaped as well, and cut to 300 characters. - CLI: on Linux, someone able to intercept the connection to the signaling server, on an untrusted Wi-Fi network for example, could do the same with a self-signed certificate. When a certificate’s names do not match the server, the error lists them as they are, and that error reached the terminal when
floe sendorfloe receivecould not connect, whenfloe sendcould not get a short code, and whenfloe receive <code>could not look one up. Every CLI release on Linux has this, v1.10.11 included. Windows checks who issued a certificate before its names, so a self-signed one never put them in the error there. - CLI: every error the CLI prints now goes through the same escape, including the signaling server’s own error messages, and so does the short code the server hands out. An error with nothing to escape prints exactly as before.
- CLI: the relay (TURN) client inside
floe sendandfloe receivewrote its own error lines to the terminal as they were, and one of them quotes the relay server’s error reply as it arrived. That reply is not authenticated, so someone on the network path to the relay could put control sequences in it during a transfer that had set up a relay connection, whether or not the files went through the relay. v1.10.11 has this too; a transfer run with--no-relaynever did. The relay client’s log lines are now off, unless you turn a pion log level on yourself with aPION_LOG_variable. - CLI: while a connection was being set up, the other side of a transfer could also make
floe sendorfloe receivehold more and more memory: nothing limited how many connection candidates it sent or how large they were, how many data channels it opened, or how large the frames waiting unread could be before the transfer started reading them. Candidates and unread data now have limits that no real Floe peer reaches, and a second data channel, which no Floe peer opens, ends the connection. v1.10.11 has this too. - Self-hosting: request links stay off until a policy file turns them on. Set
POLICY_FILEto its path; the server re-reads it every 60 seconds, so turning request links on or off needs no restart./healthnow carriesfeatures, withrequest-1while request links are on. APOLICY_FILEset to a file the server cannot find logspolicy file not found, request links offonce, the sign of a volume that was not mounted. Adocker-compose.ymlfrom before this release does not passPOLICY_FILEto the server, so take the current one first. - Self-hosting: one network can make 20 request links a day and hold at most 10 open at a time. Past 20 in a day, Floe Desktop says “This network reached today’s link limit”; past 10 open, or on a full server, it says “Couldn’t make a link”. A link closed before anyone used it answers “This link has ended” for a day, and so does a link that reached its end time unused, even while the computer that made it was asleep or off, until a day after that end. A server restart forgets both.
- Self-hosting: an address a reverse proxy writes into
X-Forwarded-Forwith a port, such as203.0.113.5:4711, now counts as the address alone, so every per-address limit holds behind such a proxy. - Self-hosting: room codes are drawn from a reviewed list of 1,247 words instead of 288, which makes a three-word code about 81 times harder to guess. A code stops working as soon as the receiver joins, when its room closes, or when the sender asks for a new one, rather than staying valid for the full 10 minutes. Each address gets 10 failed code lookups a minute, and looking up a code that works never counts against it. A code request whose room id is not a string is refused with
400. - Self-hosting: once devices at two different addresses have started connecting through a room, a device at a third address is refused as if the room were full for as long as the room exists, so someone who gets hold of the link later can no longer take the receiver’s place after it drops. A sender or receiver that comes back from a new address after that point, after switching from Wi-Fi to cellular for example, is refused the same way and needs a new link.
- Self-hosting: a web page on another site can no longer open signaling connections to your server from its visitors’ browsers. A
/wsclient that stops reading, or fakes its replies to the server’s keepalive, is disconnected instead of being held, so it can no longer grow the server’s memory or keep a seat it is not using. - Self-hosting: every per-address limit counts an IPv6 client by its /64, so rotating addresses inside it no longer gets around them, and an IPv4 address written as IPv6 (
::ffff:1.2.3.4) counts as itself. Users who share one IPv6 /64 now share its limits, as users behind one IPv4 address always have. The connection limit counts only the connections it lets in, so clients that keep retrying, or many users behind one address reconnecting after a restart, get back in as soon as older connections age out of the minute instead of staying locked out. - Self-hosting: a request from an origin that is not allowed gets
403instead of500, and a refused request logs one line, such asRefused a request with 403., instead of a stack trace. - Self-hosting: with Cloudflare’s TURN service, the server’s request to Cloudflare gives up after 10 seconds, so a hung Cloudflare API no longer stalls every client asking for relay credentials, and each failed attempt logs one
Cloudflare TURN mint failedline. Credentials are refreshed every 5 minutes instead of every 12 hours. - Self-hosting: the server image moves engine.io to 6.6.11, past a denial-of-service advisory (GHSA-2gc4-cqfq-p2gv), and the client image moves Next.js to 16.3.8 and sharp to 0.35.5, past advisories in code Floe does not use.
- Self-hosting: one setup needs a change. If the CLI or Floe Desktop reaches your server through a reverse proxy on a hostname that is not your
CLIENT_URL, the proxy must pass the originalHostheader through. Caddy and Traefik do by default, and nginx does withproxy_set_header Host $host. A proxy that rewritesHostto its upstream address, such aslocalhost:3001, now gets them refused with403(the CLI reportswebsocket: bad handshake), and the server logs one line naming theOriginand theHostit compared. Browsers on yourCLIENT_URL, a one-domain setup, and a server reached without a proxy are not affected. See Production deployment. - Self-hosting:
MAX_FAILED_CODE_RESOLVESis a new optional setting for the failed code lookups allowed per address per minute (default10). Every other setting keeps its name and default. - Self-hosting: run the client and server images at the same version, because the page a sender opens comes from the client. The published images are rebuilt as
1.11.0. These are security fixes. If you run your own server, update, and if you pinnedFLOE_IMAGE_TAG=1.10.11, move to1.11.0. - The transfer protocol version is unchanged, so this still sends to and receives from older CLI, desktop, and browser peers.
A send over a slow or lossy connection no longer fails in its last moments
- After the last file went out, Floe gave the other side 30 seconds to confirm delivery. Up to 8 MB can still be on its way at that point, so on a slow or lossy connection a send could stop at 94 to 99 percent with a delivery timeout, and the person receiving lost the file. Floe now keeps waiting as long as that remaining data is still moving, and stops only after a full minute in which nothing more gets through.
- A connection that has really stopped is still caught: when nothing moves for a minute, or the other side disconnects, the send ends as before.
- The wire protocol is unchanged, so 0.2.12 transfers with older CLI, desktop, and browser peers in both directions.
floe send no longer gives up at 94 to 99 percent on a slow or lossy connection- After the last file,
floe sendwaited a fixed 30 seconds for the receiver to confirm delivery. Up to 8 MB can still be queued at that point, so a transfer whose final stretch ran below about 1 Mbps failed withtimed out waiting for delivery confirmation from peer, and the receiver deleted the incomplete file. The sender now keeps waiting while that data is still draining, and gives up only after a full minute with no progress, the same rule the rest of a transfer already follows. - A receiver that stops responding is now reported after 60 seconds of no progress instead of a fixed 30 seconds.
- Self-hosting: the published images are rebuilt as
1.10.11. They include internal cleanups since1.10.10, sharp 0.35.4 in the client image (past a libheif advisory in code Floe does not use), and no configuration change. If you pinnedFLOE_IMAGE_TAG=1.10.10, move to1.10.11. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
Six ways to stop a signaling server with one unauthenticated request are closed
- Six different requests could end the signaling server process. Rooms are held in memory, so each one also dropped every transfer that was in progress at the time. None of them needed a room, a share code, or any credential, and the smallest was four bytes.
- Three arrived during the WebSocket handshake: a request path that Node accepts but the URL parser rejects, a client disconnecting at one precise moment, and a path spelled so that both the browser route and the command-line route claimed it at once.
- Three arrived over an established connection: a message consisting of the single word
null, a deeply nested signal, and a malformed frame on a connection that had just been rate-limited. - The server now survives an unexpected error rather than exiting, so a fault nobody anticipated costs one connection instead of every transfer on the server. All six are fixed where they happen, and the test suite fails if any of them reaches that safety net instead.
- Self-hosting: the published images are rebuilt as
1.10.10. This is a security fix. If you run your own server, update; if you pinnedFLOE_IMAGE_TAG=1.10.9, move to1.10.10. floe.one was updated separately and is already running it. - The
floecommand-line tool is unchanged in this release, and so is the wire protocol, so this still transfers with older CLI, desktop, and browser peers in both directions.
Hide my IP now says when a server cannot do it, instead of failing half a minute later with connection advice
- Hide my IP address needs the server to offer a relay, and against a self-hosted server without one the transfer used to run for about thirty seconds and then fail with “A connection could not be established. Check that both devices are online and try again.” Both devices were online. The transfer now stops immediately and names the setting, before a share code is even created, so nobody is handed a code that could never have connected.
- The Test button in Settings reports it too. A server with no relay still passes, because it works for any transfer that finds a direct path, and the result now reads Connected. This server has no TURN relay, so Hide my IP will not work. Test previously answered a bare Connected. for that server, which is what let the problem surface much later somewhere else.
- The two causes are kept apart. If Floe cannot read the server’s connection details at all, because the address is wrong, a reverse proxy is not forwarding
/api/, or the request was rate-limited, it says that rather than claiming the server has no relay. It never saw the server’s answer, so it does not guess at one. - Test also no longer accepts a server that answers with connection details containing nothing to connect with.
- The wire protocol is unchanged, so 0.2.11 transfers with older CLI, desktop, and browser peers in both directions.
--relay-only says when a server has no relay, instead of failing half a minute later with a generic timeoutfloe send --relay-onlyandfloe receive --relay-onlyagainst a server that offers no TURN relay used to wait about thirty seconds and end withtimed out establishing a connection, the same line--no-relayproduces for the opposite reason, naming neither the flag nor the server. Both now stop before the transfer starts with--relay-only needs a TURN relay and <server> offers none, and a sender stops before registering a code that could never have connected.- A second wording covers the case where the connection details could not be read at all, from a wrong
--server, a reverse proxy not forwarding/api/, or the endpoint’s own rate limit. Floe falls back to public STUN there and cannot see what the server offers, so it says so rather than blaming the server’s configuration. - Web app: when two peers cannot agree on a protocol version, the explanation each side puts on the wire is now written for whoever reads it, so a CLI or desktop peer that displays it word for word names the correct side and is not told to refresh a page. A browser that is itself the older side now reads its own remedy rather than the neutral wording. No release can trigger this today, since every peer speaks the same protocol.
- Web app: the protocol numbers inside that message are treated as text chosen by the other side, like every other value that arrives from a peer, so a hostile one can no longer reorder the error on screen or run past the length limit the rest of the message respects.
- Self-hosting: the published images are rebuilt as
1.10.9. If you pinnedFLOE_IMAGE_TAG=1.10.8, move to1.10.9. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
A small JSON file arrives intact, a file that changes while it is being sent is caught before it is sent wrong, and a transfer that is stopped on purpose says why
- A file whose entire content is one of Floe’s own control messages, such as the 14 bytes
{"type":"end"}, was read as that message and never written. A receiver now decides what an arriving frame is from how it was sent rather than from what is inside it, so a small.jsonfile arrives byte for byte. Sending one through Send text was the shortest way to hit this. - Sending a file that is still being written to now stops at the size Floe announced. A file that grew between being measured and being read, an active log or a download still running, put more bytes on the wire than promised, and the receiving end abandoned the whole batch with a message that named nothing anyone could act on. Growing and shrinking are both caught on the sending side now, and the message names the file rather than the network.
- A transfer stopped on purpose now says why. Blocking on the 2 GB relay cap, and refusing a file that did not arrive whole, both used to reach the other end as a bare disconnection; a sender with more files to send waited out the full two-minute acknowledgement deadline and then blamed a timeout.
- Receiving many files whose names collide once Windows-reserved characters are replaced is no longer slow. A thousand such files took about 42 seconds of pure filename searching before any of them were saved.
- The wire protocol is unchanged, so 0.2.10 transfers with older CLI, desktop, and browser peers in both directions.
A small JSON file arrives intact, a file that changes while it is being sent is caught before it is sent wrong, and a transfer that is stopped on purpose says why
- A file whose entire content is one of Floe’s own control messages, such as the 14 bytes
{"type":"end"}, was read as that message and never written. Every receiver now decides what an arriving frame is from how it was sent rather than from what is inside it, so a small.jsonfile arrives byte for byte. floe sendstops at the size it announced. A file that grew between being measured and being read, an active log or a download still running, put more bytes on the wire than promised, and the receiving end abandoned the whole batch withsender exceeded the announced size, which named nothing either person could act on. Growing and shrinking are both caught on the sending side now, and the message names the file’s own change.- A transfer stopped on purpose says why. Blocking on the 2 GB relay cap, and refusing a file that did not arrive whole, both used to reach the other end as a bare disconnection. A sender with more files to send waited out the full two-minute acknowledgement deadline and then blamed a timeout.
floe receiveno longer slows down on many files whose names collide once Windows-reserved characters are replaced. Seven characters that Windows refuses in a name all become_, so names that were distinct on the sending machine land on the same one; a thousand of them took about 42 seconds of pure filename searching before any were saved. What happens to those names is now written down in Known limitations.- Web app: a receiver whose sender walked away kept showing a connected badge and its last status line. It now says the transfer ended.
- Web app: a receiver used to answer every connection problem with Ask the sender to enable Network Relay, including when the sender had deliberately stopped and when the relay was already on and its 2 GB cap was the real problem. It now says what actually happened.
- Web app: a control message larger than the 1000-byte limit was written into the file being received instead of being refused. A deep enough folder path can produce one.
- Self-hosting: the published images are rebuilt as
1.10.8. If you pinnedFLOE_IMAGE_TAG=1.10.7, move to1.10.8. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
Transfer speed and time remaining are readable again, and a finished transfer stops claiming it is still using the relay
- Speeds under 1 MB/s read
0 KB/swhile bytes were moving. The reading now carries one decimal, the same as the web app and the CLI, so a slow transfer reads0.5 KB/s. - Time remaining had no hours. A long transfer read
166m 40swhere the web app and the CLI both said2h 46m. It now rolls over into hours, and it can no longer print1m 60sat the moment a minute turns over. - After a relayed transfer finished, the idle badge still showed the amber relay dot beside Ready. The route is cleared whenever a transfer ends, whether it finished, failed, or was cancelled.
- A History file that could not be read was replaced with an empty one on the next launch, so rows that might have been recovered by hand were destroyed before anyone could look. A store that fails to load is now left untouched.
- A failed settings write, which happens when the config folder cannot be written, raised an unhandled error during startup. It is now handled.
- Codes are matched without regard to capitalization, so
Olive-Tiger-Castle, which is what a phone keyboard produces, resolves the same asolive-tiger-castle. - Asking the signaling server for relay credentials or for a code now gives up after 30 seconds instead of waiting indefinitely, so a server that accepts the connection and then goes quiet no longer leaves the app waiting with nothing to show.
- A repeated message from the signaling server can no longer stall a connection that is being set up.
- Every transfer now releases the two background tasks it starts. Floe Desktop builds a fresh connection for each transfer, so these accumulated for as long as the app stayed open.
- The wire protocol is unchanged, so 0.2.9 transfers with older CLI, desktop, and browser peers in both directions.
Room codes work whatever case you type them in, and the network calls that could wait forever now give up
- A code is matched without regard to capitalization.
floe receive Olive-Tiger-Castle, which is what a phone keyboard produces, now resolves the same asolive-tiger-castleinstead of failing withcode not found or expired. Room links are unchanged: the room id in a link is still case-sensitive. floe sendandfloe receivegive the server 20 seconds to assign a role, then fail withtimed out waiting for the server to assign a role. A server that accepted the connection and then went quiet used to hang the command indefinitely. If the other side leaves during that window, the message says so instead.- Fetching relay credentials and registering or resolving a code now give up after 30 seconds. Both used to have no deadline at all.
- When the signaling server refuses a relay-credentials request,
floesays so and continues without the relay, rather than falling back in silence:Warning: signaling server returned 429 for TURN credentials. Using STUN only. - A repeated message from the signaling server can no longer stall a connection that is being set up. This is on the path every transfer takes first.
- Every transfer releases the two background tasks it starts instead of leaving them running.
floe updatecould pin its own check off permanently if the cache carried a timestamp in the future. It now treats that as expired.- Web app: files dropped in the moment between clicking Create secure link and the link appearing were counted, shown with a green check, and never sent. The file set is now sealed the moment you click, and the card shows that the link is being created rather than going blank for up to three seconds.
- Web app: a receive that ended partway through a batch reported Transfer complete. It now reads Sender disconnected. 1 of 3 files received.
- Web app: a sender whose receiver closed the tab at the wrong moment could wait forever instead of failing, and the acknowledgement timer was never cleared once an acknowledgement arrived.
- Web app: sizes are formatted safely at both ends of the range.
formatBytesreturnedNaN undefinedfor a negative number and1 undefinedpast terabytes. Time remaining could read1m 60s. - Web app: a
.gofile gets the code icon, a file with no extension at all no longer borrows one, and the relay cap beside the file count reads2 GB, matching every other place the number appears. - Web app: when a peer is too old to talk to, the message no longer tells a browser user to run a command-line tool they may not have.
- Self-hosting: the published images are rebuilt as
1.10.7. If you pinnedFLOE_IMAGE_TAG=1.10.6, move to1.10.7. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
The CLI can hide your IP address by forcing the relay, and says which route each transfer took
- A new
--relay-onlyflag onfloe sendandfloe receiveroutes the whole transfer through the TURN relay and never tries a direct path, so the other side sees the relay’s address instead of yours. It is the command-line twin of Floe Desktop’s Hide my IP address setting, applies to your side only, and can be kept on withFLOE_RELAY_ONLY=1. While it is on, the 2 GB relay cap applies to every transfer. It cannot be combined with--no-relay, and a typed--no-relayoverrides the variable for that one command. - Once the connection is up, the
Connectedline names the route:Connected (direct)when the two devices talk to each other,Connected (relay)when the transfer runs through the TURN relay. If the route cannot be read, the line staysConnectedand the transfer proceeds as before. A script that matched that line exactly should match on theConnectedprefix instead. - Against a server that offers no TURN relay,
--relay-onlyhas nowhere to go and fails after about 30 seconds withtimed out establishing a connection, the same generic timeout--no-relayproduces when no direct path exists. - Web app: the privacy policy’s opt-out instructions now name Floe Desktop’s Settings switch alongside the browser checkbox and the CLI’s
--no-report. Only the wording was incomplete; all three opt-outs already worked. - Self-hosting:
GET /api/confignow returns acommitfield next tosocketUrl, naming the source revision the client was deployed from, so anyone can check which build an instance is running. SetSOURCE_COMMITin the client container’s environment to fill it in; it reportsnullwhen unset. Compose does not pass the variable through, so add it to the client service yourself if you want it served. - Self-hosting: the published images are rebuilt as
1.10.6. No Floe code changed in either one; the client image picks up Next.js 16.3.3 and the server image picks upws8.21.3. Next.js 16.3.3 is a security release for two advisories rated critical, and neither one reaches Floe as it ships: one needs a Windows host and both images are Linux, and the other needs an AVIF image through the optimizer, which the client does not enable. So pull when convenient rather than urgently. If you pinnedFLOE_IMAGE_TAG=1.10.5, move to1.10.6. - The wire protocol is unchanged, so this still transfers with older CLI, desktop, and browser peers in both directions.
A file name chosen by the other side can no longer disguise its extension in the incoming preview, and an impossible file size no longer closes the app
- The incoming preview shows a cleaned name: control characters and text-direction marks become underscores, and a name longer than 200 characters is shortened with its extension kept. The name saved on disk is unchanged, and the progress line and History show the name as it was saved.
- A sender that announced a negative or impossibly large file size ended the whole app before the preview appeared. Sizes and file counts are now checked as the announcement arrives, and an announcement that cannot be right ends the transfer with an error in the status line instead.
- A file that keeps arriving past the size the sender announced is stopped at the first extra byte and the partial file is removed.
- The status line shows cleaned messages from the shared engine, including the version string and rejection reason a peer sends back.
- A control message longer than 1000 bytes ends the transfer with an error instead of being parsed, and a receiver that asks to resume from a position outside the file is refused.
- The fix is on the receiving side, so a transfer is protected once the receiving end runs Floe Desktop 0.2.8 or
floe1.10.5. The wire protocol is unchanged, so 0.2.8 transfers with older CLI, desktop, and browser peers in both directions.
A file name or version string chosen by the other side can no longer rewrite the terminal, disguise its extension in the accept prompt, or crash the receiver
floe receiveshowed the sender’s file name exactly as sent in the Incoming box and theAccept? [Y/n]prompt. The name was only cleaned later, when the file was written, so a name containing terminal control codes could erase or redraw the prompt, and a text-direction mark could makephotofollowed by a reversedexe.pngread as an image while the file was a program. The Incoming box, the accept prompt, the peer version note, progress reporting, and every error message now show a cleaned name: control characters and text-direction marks become underscores, and names longer than 200 characters are shortened with the extension kept. The name saved on disk is unchanged.- A sender that announced a negative or impossibly large file size made the receiver crash before the prompt appeared. Sizes and file counts are now checked as the announcement arrives, an announcement that cannot be right ends the transfer with an error instead, and
floe sendshows that reason rather than only reporting a closed connection. - A file that keeps arriving past the size the sender announced is stopped at the first extra byte and the partial file is removed, instead of the overrun being caught only when the file ends.
- A receiver that asks to resume from a position outside the file is refused by
floe send, instead of the transfer hanging or sending nothing. floe receivenow ends the transfer with an error when a control message is longer than 1000 bytes, instead of parsing it, matching the limit the web app has always enforced.floe senddrops such a frame and keeps waiting for a valid one.floe sendcleans and shortens the version string and the rejection reason a receiver sends back before printing them.- Web app: the error shown when a file arrives incomplete, and the message shown when the other side rejects a transfer, have control characters and text-direction marks removed and are shortened before they appear on the page. The web app also refuses a resume position outside the file instead of sending nothing forever.
- Self-hosting: the published images are rebuilt as
1.10.5. Nothing in the server changed, so pull when convenient. If you pinnedFLOE_IMAGE_TAG=1.10.4, move to1.10.5. - The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.5 or Floe Desktop 0.2.8; sending from an updated build to a peer that has not updated is unchanged. The wire protocol is unchanged, so v1.10.5 still speaks to older CLI, desktop, and browser peers in both directions.
A killed transfer never leaves a half-written file looking finished, closing mid-transfer asks first, and Send with Floe keeps every file
- A received file is now written under a temporary name ending in
.partand takes its real name only once every byte has arrived. Before this, closing the window, ending the app from Task Manager, or losing power partway through left the unfinished file in your folder under its final name, looking complete. Now the worst that can remain is a.partfile, which is safe to delete. - Closing the window during a transfer asks first. A new prompt offers Keep going or Close anyway, so one stray click on the close button no longer cuts a transfer off for both sides with nothing on screen.
- Send with Floe on several files at once now sends all of them. Windows starts Floe once for each file you select, and files that arrived before the window finished loading used to be silently dropped, so a five-file selection could send only one. Every selected file now lands in the same window.
- The file name that is shown and the one that is saved stay in step even when a name collision is only discovered as the file finishes, so Open and Show in folder always act on the file you actually received.
- No transfer-protocol change, so Floe Desktop 0.2.7 transfers with browser and CLI peers in every direction.
Received files are written under a temporary name and only renamed when complete, so a killed transfer never leaves one looking finished
floe receivenow writes each file under a temporary name ending in.partand renames it to its final name only after every byte has arrived and been verified. A transfer killed outright, or a machine that loses power partway through, can no longer leave a half-written file under a finished-looking name; the worst that remains is a.partfile, safe to delete. On Windows the final rename is atomic; on macOS and Linux a crash at the exact instant of completion can leave an empty placeholder beside the intact.part.Ctrl+Cremoves the in-flight.partfile on the way out, so a canceled receive leaves the output directory clean.- The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.4 or Floe Desktop 0.2.7; sending from an updated build to a peer that has not updated is unchanged. - Self-hosting: the published images are rebuilt as
1.10.4. This release only touches the receive path the CLI and desktop app share, so there is nothing you need to do; pull when convenient. If you pinnedFLOE_IMAGE_TAG=1.10.3, move to1.10.4. - The wire protocol is unchanged, so v1.10.4 still speaks to older CLI and browser peers in both directions.
Files whose names Windows cannot hold now arrive intact instead of arriving empty
- A file sent from a Mac or a Linux machine can carry a name Windows has no way to store. A timestamp like
backup:2026-08-19.logis the everyday case, because Windows gives the colon a special meaning. Floe used to write that file, report success, and leave you an empty file calledbackup, with the contents routed somewhere you would never find them. Names likewhat?.txtwere worse still: the file could not be created at all, and the error ended the rest of the batch, so files queued behind it never arrived. - Incoming names are now adjusted before the file is written. The characters
< > : " | ? *become underscores, trailing dots and spaces are removed, and a name that is a reserved device name such asNULgets an underscore in front. The progress line and Show in folder both use the adjusted name, and two files that end up with the same adjusted name are numbered the way colliding names always have been. - A file named with a trailing space used to lose its mark of the web, the tag that makes Windows treat a received file as downloaded from the internet. The tag attached to the wrong name and the saved file kept none, so SmartScreen and Office Protected View stayed out of the way on a file a stranger sent you. Received files are now tagged correctly whatever they are called.
- Control characters and text-direction marks are removed from incoming names on every platform. A text-direction mark can make
photofollowed by a reversedexe.pngread as an image in the file list while the file on disk is a program. - Folder sends keep their structure. Each part of the path is adjusted on its own, so a folder that needed adjusting stays a folder.
- No transfer-protocol change, so Floe Desktop 0.2.6 transfers with browser and CLI peers in every direction.
Received files that a system cannot store, and browser downloads that were never complete, no longer pass as finished
floe receiveadjusts an incoming file name that the receiving system cannot represent, instead of writing it and reporting success. On Windows a name likebackup:2026-08-19.logused to leave an empty file calledbackup, a file calledNULleft nothing at all, and a name containing?could not be created and ended the rest of the batch. macOS and Linux keep names exactly as sent, since all of those are valid there.- On Windows, a received file named with a trailing space used to lose its mark of the web, so SmartScreen and Office Protected View did not apply to it. That tag now attaches correctly whatever the file is called.
- Control characters and text-direction marks are removed from incoming names on every platform, and the receiver refuses to write onto a device rather than discarding the contents silently.
- The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.3 or Floe Desktop 0.2.6; sending from an updated build to a peer that has not updated is unchanged. Both surfaces ship the fix in this pair of releases. - Web app: a file that arrived incomplete is no longer offered as a finished download. The browser labeled each file with however many bytes turned up rather than the number the sender announced, so the two could never disagree and a file cut short still showed a checkmark and a working download button. It is now checked against the announced size and refused if it does not match, and a short count is no longer added to the public transfer counter.
- Web app: sending a file that becomes unreadable partway through, because it was moved, renamed, or sat on a drive or cloud folder that went away, now reports the failure instead of telling both sides the file finished.
- Web app: file names chosen by the sender are cleaned before they are used to name a download or an entry in a ZIP, so a name cannot describe a path or quietly drop a file from the archive.
- Web app: a transfer blocked by the 2 GB relay cap now closes the connection and explains itself, instead of leaving the other side waiting with nothing on screen.
- Self-hosting: the published images are rebuilt as
1.10.3and carry the web app changes above. To pick them up:docker compose pullthendocker compose up -d; if you pinnedFLOE_IMAGE_TAG=1.10.2, move to1.10.3. - The wire protocol is unchanged, so v1.10.3 still speaks to older CLI and browser peers in both directions.
Empty a staged selection in one click, and a fix for transfers that connected but never started
- A Clear button now sits beside Send on the send card. It empties whatever the tab you are on is holding, the file list on Files or the box on Text, and leaves your settings, the Receive tab, your history and the files themselves alone. It appears only when there is something to clear, and steps aside for Cancel while a send is running.
- Clear does not ask first. It offers Undo instead, in a bar at the bottom of the window that puts back exactly what you had staged, whitespace and all. The bar shows for about ten seconds, longer while you point at it or reach it with the keyboard.
- The undo outlasts the bar.
CtrlZstill takes it once the bar has gone, and it stands until you put something new on that same tab, clear something else, or start over. Switching tabs, opening Settings or checking History only puts the bar away, and it comes back when you do. Like the app’s other shortcuts,CtrlZwaits while the cursor is in a text box. - Start over now asks before discarding a note you have cleared, the same way it already asks about a note you typed but never sent.
- Fixed transfers that connected and then moved nothing: both ends showed a healthy connection, then sat silent until a timeout blamed the other side. The very first message of a transfer could be dropped before the receiving app was listening for it. The odds turn on the round trip between the two peers, so it was rare across a network and common between two Floe apps on one machine. The fix is on the receiving side, so a transfer is protected once the receiving end is running Floe Desktop 0.2.5 or
floe1.10.2. Sending from this build to a peer that has not updated is unchanged. - Every row in History is now a single button that opens and closes the row, with one chevron in the same place on every row. The opened row carries the file names, and for a received transfer where it was saved plus a Show in folder action; every row carries Remove. Finishing a transfer no longer shifts which row is open, because a new entry goes on top and the open row used to be tracked by position.
- The dashed borders on the drop area read as soft white now and brighten when you point at them. The blue is kept for the highlight that appears while you are actually dragging files over the window.
- Turning off animations in Windows now stops the app’s own animations. The setting was being ignored, so the update notice, the Settings panel, tooltips, the connection dot and the new undo bar all moved anyway.
- The focus outline on buttons is brighter, so it is easier to see where the keyboard is.
- No transfer-protocol change, so Floe Desktop 0.2.5 transfers with browser and CLI peers in every direction.
Fixed transfers that connected and then moved nothing
- A transfer could reach the point where both ends reported a healthy connection and then never start, ending 30 seconds later with
connected, but no data arrived from the senderon one side and a message blaming the receiver on the other. The very first message of a transfer could be dropped before the receiving side was listening for it, and because the network layer had already accepted that message, nothing ever resent it. - The window is microseconds wide and closes as the round trip between peers grows, so it was rare between two machines and common between two Floe processes on one machine. It has been there since the first release.
- The fix is on the receiving side. A transfer is protected once the receiving end is running
floe1.10.2 or Floe Desktop 0.2.5; sending from an updated build to a peer that has not updated is unchanged. Both surfaces ship the fix in this pair of releases. - Self-hosting: the published images are rebuilt as
1.10.2with nothing of their own changed, since this release only touches the transfer engine the CLI and the desktop app share. There is nothing you need to do; pull when convenient. - The wire protocol is unchanged, so v1.10.2 still speaks to older CLI and browser peers in both directions. That is a statement about compatibility, not about the bug above, which is fixed for whichever end is running the new build.
A cleaner update notice, and the main screen says precisely what happens to your files
- The update notice is redrawn as a slim one-row frosted bar with a whisper of ice in its border. What it does is unchanged.
- The main screen’s subline now promises “no uploads” instead of “no middleman”. A relayed transfer does pass through a relay, so the old word claimed too much; nothing is uploaded on any path.
- No transfer-protocol change, so Floe Desktop 0.2.4 transfers with browser and CLI peers in every direction.
Failed or stalled receives clean up their partial file
floe receiveno longer leaves a half-written file behind under its final name when a transfer fails or stalls. The partial is deleted, files that completed earlier in the batch are kept, and a retried transfer gets its original name back instead of a numbered one.- The protocol-incompatibility message the CLI sends across the wire is now worded from the reader’s perspective, so older versions that display it word-for-word name the correct side. No release can trigger this today (every peer speaks the same protocol).
- Web app: the navbar now adapts to window width in three steps instead of two, and the Download link is visible at every size; it previously appeared only on wider windows, so the header offered no way to reach the desktop app’s download page on a phone.
- Web app: floe.one and the docs now share the same four-column footer (Product, Documentation, Project, Legal), and it appears on every page of the site rather than only the homepage and the download page.
- Web app: fixed the docs pages showing outdated content that a reload could not refresh; an offline cache was keeping old copies forever, and they now clear automatically on your next visit.
- Self-hosting: the published images carry every web-app change above plus updated dependencies (Next.js 16.3.0 and
ws8.21.2). To pick them up:docker compose pullthendocker compose up -d; if you pinnedFLOE_IMAGE_TAG=1.10.0, move to1.10.1. - No transfer-protocol change, so v1.10.1 interoperates with older CLI and browser peers in every direction.
Failed transfers clean up after themselves and speak plainly, and Start over stops losing notes
- A receive that fails or is cancelled partway no longer leaves a half-written file behind under its final name. The partial is deleted, files that completed earlier in the batch are kept, and a retried transfer gets its original name back instead of a numbered one.
- The Receive card now shows what is incoming (the file name and size, or the file count and total) the moment the sender is known, before the first byte arrives.
- A failed receive now raises a Windows notification like a failed send always did, and cancelling a transfer no longer raises a false “send failed” one.
- Transfer errors are now written for people (“The connection was lost before the transfer finished. Start it again.”) instead of surfacing the engine’s internal wording. Genuinely unknown failures still show the raw text so bug reports stay useful.
- Cancelling a transfer and immediately starting another no longer lets the dead attempt interfere: its late events are ignored, it can no longer release the keep-awake lock the new transfer holds, and Cancel always reaches the transfer that is actually running.
- The app now checks GitHub once a day for a newer desktop release and shows a small dismissible notice when one exists, with a matching row in Settings under About. GitHub-channel builds only: the Microsoft Store build never checks, because the Store updates it itself. Nothing downloads or installs by itself. A new Check for updates switch in Settings under Privacy turns the check off, and off means no request is made at all.
- Protocol-incompatibility messages now name the remedy for the surface you are on: the desktop app points at the Microsoft Store or floe.one/download instead of the CLI’s
floe update, and the message sent across the wire is worded from the reader’s perspective, so older versions that display it word-for-word name the correct side. No release can trigger this today (every peer speaks the same protocol); it prepares the messaging for any future wire change. Contributed by the project’s first external code contributor. - Fixed Start over still discarding a typed note without asking, in the two cases the 0.2.2 fix missed. Typing a new note after a send completed, and typing a note then switching to Files and sending those instead, both left text in the box that had never gone anywhere, and both were cleared with no prompt. Floe now compares the box against what the last completed send actually put on the wire, so a note only counts as sent while it is still exactly the note that went out. Tidying up after a send with the sent note still in the box is unchanged and still silent, as is starting over while a connection is being set up.
- Fixed a failed transfer leaving its progress bar frozen on screen underneath the error, on both the sending and the receiving side.
- Fixed Start over offering to cancel a transfer that had already failed. The stale progress bar above was also what the confirmation read, so after a failure it warned about cancelling a transfer that was already over, and that warning hid the one about the unsent note behind it.
- No transfer-protocol change, so Floe Desktop 0.2.3 transfers with browser and CLI peers in every direction.
Stalled transfers now fail with a reason, and received files are never overwritten
floe sendandfloe receiveno longer wait forever when a connection half-forms. Waiting for the peer’s offer or answer is capped at 30 seconds, establishing the connection at 30 more, with a 10 second grace for the data channel once the peers are otherwise connected. Each says which stage gave up:timed out waiting for the peer's offer,timed out establishing a connection,connected but the data channel did not open. None of this limits how long a sender waits for a receiver to arrive, which is still unbounded, so sharing a code and walking away works exactly as before.floe receiveno longer overwrites an existing file that has the same name as an incoming one. The new file is saved with a numbered suffix before the extension (report.pdf, thenreport (1).pdf), the same way browsers de-duplicate downloads. The progress line shows the name actually written.- On Windows, received files are now tagged with the mark of the web (a
Zone.Identifierstream), so SmartScreen and Office Protected View treat them like browser downloads when opened. FLOE_SERVERandFLOE_WEBset the server and web addresses for every command, so a self-hosted setup no longer repeats--serveron each one. An explicit flag still wins over the environment.- A trailing slash on a self-hosted server address no longer kills the transfer.
--server https://example.com/builthttps://example.com//api/code, which answers 404, and that 404 was swallowed into a silent fall back to public STUN, so a relayed transfer failed with nothing to explain it. Surrounding whitespace and any run of trailing slashes are now trimmed. - A receive code that has already been used says
this code is no longer active; ask for a new one. It used to report an unexpected role, which described the internals rather than the situation. - Web app: session replay is gone from floe.one. Recordings masked all text and media, so file names and contents were never captured, but a recording reported the page address, and a receiver’s address carries the room link. That link is the only thing protecting a transfer. It is now stripped from error reports and breadcrumbs too.
- Web app: the analytics script no longer receives the room link either. It reported the full address on page load, so a receiver opening a share link handed the room secret to a third party. It now sees the path alone.
- Web app: floe.one sends a content security policy that refuses to be framed, alongside
X-Content-Type-Options,Referrer-Policy,Permissions-Policyand HSTS. - Self-hosting: the published images run Node 24, the Active LTS, again. A dependency update had moved them to Node 25, which reached end of life on 2026-06-01 and will receive no further security patches.
- Self-hosting: the signaling server no longer returns a stack trace when a request fails. It answers with a plain JSON error instead.
- Self-hosting: the room-code word list is deduplicated and extended to 288 unique words. Thirteen words appeared twice, which made some phrases likelier than others and left only 275 distinct ones.
- No transfer-protocol change, so v1.10.0 interoperates with older CLI and browser peers in every direction.
A redrawn app icon, and two things that used to fail silently
- The app icon is redrawn to match the mark on floe.one: a larger bolt with rounded corners, at the proportions the website already used. The squircle keeps its depth, which the flat website favicon has no use for.
- On a Store install, Windows no longer draws a coloured square behind the icon on the taskbar, in Start, in search and in Alt+Tab. The package was missing the unplated icon assets Windows looks for, so it fell back to plating the icon; 0.2.1 only changed what colour that square was. Installs from GitHub were never affected.
- Fixed the app exiting without a word when it could not start. Release builds have no console, so a failure before the window appeared killed the process in silence. The one cause you can act on is a missing WebView2 runtime that Floe could not download, offline or behind a filtering proxy, and that now raises a message box naming it. Failures raised inside the window toolkit itself can still end the process quietly.
- Fixed Start over throwing away a typed note without asking.
CtrlRis now ignored while the cursor is in a field, and starting over from idle asks first when a note is waiting to be sent. It stays silent while a connection is being set up, and just after a send, on purpose: Start over is the way out of a connection that will not settle. Staged files are still cleared without a prompt, since the files themselves are untouched on disk. - Corrected the encryption note in the sidebar. Floe’s data channel is secured by DTLS; the note also credited SRTP, which protects the audio and video streams that Floe never sends.
- No transfer-protocol change, so Floe Desktop 0.2.2 transfers with browser and CLI peers in every direction.
A darker tile behind the Store icon
- On a Microsoft Store install, the square Windows drew behind the Floe icon took the system accent colour, which is a bright blue on a default Windows setup. It is now the brand dark, so the tile reads as one piece with the icon. Removing that square altogether came later, in 0.2.2.
- The installer and portable zip published under this tag behave exactly as 0.2.0 does. The change lives in the Store package manifest, so there is nothing to gain by downloading them.
- No transfer-protocol change, so Floe Desktop 0.2.1 transfers with browser and CLI peers in every direction.
Floe Desktop arrives on the Microsoft Store
- Floe Desktop is now on the Microsoft Store. Microsoft re-signs the package, so it installs with no “unknown publisher” warning and updates itself in the background. This is the recommended way to install it.
- The installer and portable zip on GitHub continue in parallel and are not going away. They serve machines without Store access, and they are the fallback if a Store update ever goes wrong. Those builds are unsigned, so Windows still warns on first run.
- The Show in right-click menu setting is hidden on a Store install, along with the Windows section of Settings that contains it. A packaged app’s registry writes land in a private view that File Explorer never reads, so the entry could be written but would never appear. The GitHub build still offers it.
- Both builds keep their settings in the same place, so switching between them, or between the desktop app and the
floeCLI, keeps your server address and preferences. - Desktop releases carry their own
desktop-vX.Y.Znumbers, separate from thevX.Y.Ztags that release the CLI and the server. The two lines never need to match. - No transfer-protocol change, so Floe Desktop 0.2.0 transfers with browser and CLI peers in every direction.
Floe Desktop, the first beta
- A native Windows app, and the third way to use Floe alongside the web app and the CLI. It runs the same transfer engine as the CLI, so it sends to and receives from browser peers and CLI peers with no extra setup. See Floe Desktop.
- Send files, whole folders without zipping, or a typed note. Add them with the picker, by dropping them anywhere on the window, or with
CtrlVfor files copied in File Explorer and for screenshots straight off the clipboard. - Receive with a room code or a share link, choose where files land, then open the file or reveal it in File Explorer. Nothing is ever overwritten, and received files are tagged as downloads so Windows applies its usual caution.
- A local history of the last 50 transfers, a Windows notification when one finishes, and the machine is kept awake while a transfer is connected.
- Settings cover the save folder, a Hide my IP mode that routes everything through the relay, the global-stats opt-out, the File Explorer Send with Floe entry, and a self-hosted server address with a Test button that checks the three endpoints a transfer actually needs.
- The installer is per user, so there is no administrator prompt, and uninstalling leaves your settings and history in place.
- Relayed transfers are capped at 2 GB per session, the same rule the web app and the CLI already apply. Direct transfers have no limit.
- No transfer-protocol change, so Floe Desktop 0.1.0 transfers with browser and CLI peers in every direction.
A self-hosting image fix. The CLI is unchanged.
- Fixed the self-hosted web client re-encoding every image on every request instead of caching it.
/app/.nextwas owned byrootwhile the server runs asnode, so the image cache could never be written. Pages rendered correctly throughout, which is why it went unnoticed: the only symptoms were wasted CPU on every request and anEACCESunhandled rejection in the container logs each time. This affects1.9.0, andlatestas it stood before this release. - To pick it up:
docker compose pullthendocker compose up -d. If you pinnedFLOE_IMAGE_TAG=1.9.0, move to1.9.1. docker-compose.ymlnow defaults to thelatestrelease rather thanmain, so a fresh install tracks releases instead of every merged commit. This could not ship in v1.9.0 itself:latestis created by the release, so a compose file inside that release could not have pointed at it. SetFLOE_IMAGE_TAG=mainif you prefer to stay onmain.- The CLI is identical to v1.9.0. It is republished only because the CLI and the container images share one version number, so a
floeupgrade offered by Homebrew, Scoop, or winget changes nothing for you. There is no need to update it. - The smoke test that every image must pass before a tag points at it now asserts that a repeat image request is served from cache. The existing checks all passed while this was broken, since the response stayed a valid WebP with a 200 status, so nothing in it revealed the problem.
- No transfer-protocol change, so v1.9.1 interoperates with older CLI and browser peers in every direction.
Self-hosting without a clone, on any common hardware
- Prebuilt images are published to
ghcr.io/jannskiee/floe-serverandghcr.io/jannskiee/floe-client, anddocker-compose.ymlpulls them. A working instance is two commands: download the compose file, thendocker compose up -d. No repository, no Node, no Go, nothing compiled locally. See Container Images. - Both images are published for
linux/amd64andlinux/arm64, so Raspberry Pi, Oracle Ampere, AWS Graviton, and Apple silicon run exactly the same two commands. Docker selects the right architecture automatically. - A
.envfile is genuinely optional. Every setting has a working default. - Pin a version with
FLOE_IMAGE_TAG, or pin a digest for a build that can never move. - Each architecture is built and smoke-tested on its own hardware, and a tag is published only after every architecture of both images passes, so a partly-built release is never visible. That matters because the image optimiser fails silently: when it cannot load it serves the original file rather than erroring, so a broken image would look healthy to anything that only checks whether the page loads.
- The published client no longer emits canonical links, Open Graph images, or sitemap entries pointing at
floe.one. A shared image cannot know which domain it will be served from, so it claims nothing rather than advertising somebody else’s site. To use your own domain, build the client withNEXT_PUBLIC_SITE_URLset. - Contributors build from source with
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build. - Both images move to Node 24, the Active LTS. The server was on Node 20, a Maintenance release.
- CLI:
floe versionand the help text now point atfloe.one/docsrather than the retireddocs.floe.one, and the WebRTC stack moves to pion 4.2.18. - 32-bit ARM (
linux/arm/v7) is not published: Node dropped support for it and no prebuilt image-processing binaries exist. - No transfer-protocol change, so v1.9.0 interoperates with older CLI and browser peers in every direction.
The 2 GB relay cap now applies to the CLI, plus honest receiver errors
floe sendnow enforces the same 2 GB relay session cap as the web app. Once the connection is established, the sender checks the selected route: if it runs through the TURN relay and the queued files total more than 2 GB, the transfer is blocked before any data moves, with a clear error. Direct connections keep no size limit, and a connection whose path cannot be determined is never blocked. See The 2 GB Relay Limit.- Fixed the receiver treating a sender that disconnected before the first file as a successful transfer:
floe receiveexited silently as if nothing was expected, and a multi-file batch interrupted between files was reported as complete. Both cases now end with a clear error describing what actually arrived. - CLI errors no longer print the full usage reference after the message. A failed transfer or an expired code now shows the one-line error alone.
- No transfer-protocol change, so v1.8.0 interoperates with older CLI and browser peers in every direction.
Stalled transfers now fail fast with clear errors
- Fixed transfers freezing forever when the connection silently broke right after setup. The receiver now reports “connected, but no data arrived from the sender” within 30 seconds if the transfer never starts, and “transfer stalled” with exact byte progress if data stops flowing mid-file for a full minute, instead of sitting on a frozen progress bar until you press Ctrl+C. These stalls are rare, but when one happened there was no way to tell it apart from a slow transfer.
- Fixed
floe sendwaiting up to two minutes after the receiver declined the transfer or exited. It now reports “connection closed while waiting for the receiver” in about a second. - Web app: the share link now appears only once the server has confirmed your room. This closes a rare race where a receiver that followed the link extremely quickly could be mistaken for the sender and fail with a role error.
- Updated the CLI’s WebRTC stack (Pion) to the current releases.
- No transfer-protocol change, so v1.7.6 interoperates with older CLI and browser peers in every direction.
Accurate progress on slow connections, and a CLI relay fix
- Fixed the sender’s progress running far ahead of the receiver. The sender counted bytes handed to the connection’s send buffer rather than bytes that actually reached the other side, so on slower or relayed connections its bar raced ahead by up to 8 MB, froze for up to a minute while the buffer drained, moved to the next file before the receiver finished the previous one, and showed “All Files Sent!” while the receiver was still downloading. The sender now reports delivered bytes: both sides move together at the real network speed, the file counter stays in step, and completion means the receiver has everything.
- Fixed the receiver’s progress bar barely updating since the larger transfer blocks introduced in v1.7.3. It could sit still for minutes on slow connections (and never move at all for files under 6.25 MB), which looked like a stalled transfer. It now updates at least every 1 MB regardless of block size.
- Fixed
floe sendgiving up with a “backpressure stall” error on relayed connections slower than roughly 70 KB/s. The CLI now aborts only when the connection makes no progress at all for a full minute, instead of whenever draining simply takes longer than a minute. - Web app: the connection badge tooltip and the Network Relay Fallback description now explain that direct peer-to-peer connections are the norm even across different networks such as mobile data, and that the relay is only a fallback used when a direct path cannot be established.
- No transfer-protocol change, so v1.7.5 interoperates with older CLI and browser peers in every direction.
Faster connection setup
- Fixed connections taking 20 to 30 seconds to establish on machines running VPN or virtual machine software (Tailscale, VMware, WSL, Hyper-V). Two causes were addressed: the signaling server handed every client a redundant list of eight relay endpoints where three suffice, and the CLI probed dead auto-configuration network interfaces during setup. The server-side fix is already live and speeds up all existing versions, browser included; this release adds the CLI-side hardening so connections stay fast against any server, including self-hosted ones.
- Added an advanced
--ifaceflag to restrict the CLI to specific network interfaces by name (for example--iface Ethernet), useful for pinning a transfer to a chosen network. Most users never need it. See the flags reference. - Web app: opening a fresh share link in a tab that already had Floe open now joins the new room correctly instead of reusing the old session.
- No transfer-protocol change, so v1.7.4 interoperates with older CLI and browser peers in every direction.
Faster CLI transfers, and a browser-to-CLI reliability fix
floe sendnow sends file data in larger blocks, sized to what the connection negotiates (up to 256 KB) rather than a fixed 16 KB. On fast paths such as a local network or a direct connection, this removes most of the per-block overhead and noticeably increases throughput. Relayed or slower connections are unaffected, since their speed is set by the link rather than the block size.- Fixed browser-to-CLI transfers that could fail with a timeout when the person running
floe receivetook more than 15 seconds to accept the incoming files at the prompt. The browser now waits as patiently as the CLI already did. - No transfer-protocol change, so v1.7.3 interoperates with older CLI and browser peers in every direction.
CLI: share links keep the room secret in the URL fragment
floe sendnow prints ahttps://floe.one/#room=<id>link. The room id sits in the URL fragment (after the#), which a browser never sends to the web server, never puts in theRefererheader, and never exposes to pageview analytics. Previously it was a?room=query parameter that could reach those places when a recipient opened the link in a browser. This brings the CLI in line with the web app.floe receiveresolves a#room=link, a legacy?room=link, or a short code, so links shared by any version keep working.- No transfer-protocol change, so v1.7.2 interoperates with older CLI and browser peers in every direction.
Reliable global-counter reporting for the CLI
- Fixed CLI transfers not always being counted in the global homepage counter. The receiver’s byte-count report was sent in the background and could be cut short when the sender closed the connection and the process exited, so larger transfers (several GB and up) were frequently missed and smaller ones counted only intermittently.
- The report now completes before the program exits, so a successful CLI transfer of any size contributes exactly once. The report still carries only the byte count (never file names or contents), still never blocks or slows the transfer, and opting out with
--no-reportorFLOE_NO_STATS=1is unaffected. - Browser transfers were never affected by this issue.
Global transfer counter with opt-out
- Added a public, all-time counter of total bytes transferred across every Floe user, shown on the homepage with a rolling-number animation. The number rolls up from zero on each visit and ticks higher as transfers complete worldwide.
- The counter is fed without ever touching your files. After a transfer finishes, only the receiving side reports the byte count (never file names or contents). The sender never reports. The stored value is a single anonymous total, not linked to any user, transfer, or IP address. See Security and Privacy for the full data-handling note.
- The CLI receiver now contributes to the global counter. The total is viewable only in the browser; the CLI never fetches or displays it.
- Both the browser receiver and the CLI receiver support opting out. Browser: uncheck “Contribute to global stats” on the receiver view (saved to your browser). CLI: pass
--no-reporttofloe receive, or setFLOE_NO_STATS=1in your environment for a permanent opt-out. The transfer is unaffected either way. - Self-hosters can opt in by pointing the server at a free Upstash Redis database (
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN). Without it, the counter still works but resets on restart. See Configuration.
Protocol version negotiation
- Added a wire protocol version that the sender and receiver exchange when a transfer starts. It is separate from the release version (1.6.x), so peers on different releases still transfer normally. A patch or minor difference such as v1.5.4 and v1.5.5 is never a conflict and is never blocked.
- If a future release ever changes the wire format in a breaking way, the two sides now detect it before any file data moves and print a clear “your floe is too old, run
floe update” message (or “ask the other side to update”) instead of failing with a confusing error or a corrupt file. - Works in every direction: CLI-to-CLI, browser-to-CLI, and CLI-to-browser. Older peers that predate this change are treated as the baseline protocol and stay fully compatible.
floe update permission fix- Fixed
floe updatefailing with “permission denied” when floe is installed in a root-owned directory such as/usr/local/binon Linux and macOS. The updater now downloads and extracts as the current user, installs directly when the location is user-writable (for example~/.local/bin), and automatically requests sudo only for the final atomic swap when it is not. To upgrade from an older version one time, runsudo floe update; after that plainfloe updateworks.
CLI progress bar fix
- Fixed the transfer progress bar printing a new line for every percentage on narrow or Windows terminals. The bar now sizes itself to the terminal width so the line never wraps, and it updates in place on a single line per file.
Installer and self-update download fix
- Fixed a 404 when installing or updating floe. The install scripts (
install.sh,install.ps1) and the built-infloe updaterequested the release archive with a leading “v” in the version (for examplefloe_v1.5.2_linux_arm64.tar.gz), but the published asset name omits it (floe_1.5.2_linux_arm64.tar.gz). All download paths now use the correct filename. This affected every platform and architecture, including Raspberry Pi (linux/arm64).
CLI stability fix
- Fixed a rare concurrent-write panic in the CLI signaling client. Rapid ICE candidate negotiation could trigger simultaneous WebSocket writes from separate goroutines; all writes are now serialized.
CLI output improvement
- The
Sendingsummary line (file name and total size) now appears above the sharing box, so you can see what is being sent before the peer connects.
File summary on both sides
- Both the sender and the receiver now see a file count and total size before and after the transfer. Example:
Sending 3 files · 11.8 MBon the sender side andIncoming 3 files · 11.8 MBon the receiver side.
CLI-to-CLI transfer fix
- Fixed an error reported by the CLI sender after a successful CLI-to-CLI transfer. The transfer completed correctly but the sender exited with an error code. It now exits cleanly.
One-command install and self-update
floe updatenow works on all platforms (script installs, manual installs). It downloads, verifies, and replaces the running binary in one step.- Re-running the install script (
curl -fsSL https://floe.one/install.sh | shorirm https://floe.one/install.ps1 | iex) also upgrades an existing install in place. - If floe was installed via Homebrew, Scoop, or Winget,
floe updatedetects this and prints the correct package manager command instead. - Fixed a browser receiver bug where a
Bufferview was retained across chunk boundaries instead of being copied, which could corrupt received data. - Security: updated
ws,esbuild, andpostcsstransitive dependencies to address published advisories.
Rich transfer summary
-
At the end of each transfer, the CLI now prints a boxed summary with the total data transferred, elapsed time, and average speed. Example:
-
The receiver summary also includes the
Saved topath.
Transfer reliability and browser fixes
- Fixed several CLI transfer sync bugs that could cause stalled or incomplete transfers, especially in CLI-to-CLI sessions. Added cross-implementation loopback tests to prevent regressions.
- Fixed an issue where the in-app browser detection could steal the receiver slot from a legitimate peer, preventing the transfer from starting.
- Fixed duplicate WebRTC signal handling that could break transfers after a reconnect.
- Redesigned the in-app browser warning page for clarity.
- Upgraded the CLI to Pion WebRTC v4 (includes Pion DTLS v3).
- Performance: improved browser-to-browser transfer throughput with better backpressure tuning.
Initial public release
- Browser-based peer-to-peer file transfer at floe.one. No account, no installation, no file storage.
floeCLI for macOS, Linux, and Windows. Fully interoperable with the browser client.- End-to-end DTLS encryption on all transfers, direct and relayed.
- Optional TURN relay fallback for peers behind strict firewalls or carrier-grade NAT (capped at 2 GB per session).
- Self-hosting support via Docker Compose. See Self-Hosting.
- Mintlify documentation site at docs.floe.one.