Finding · Egnyte · APIs · Backups
Egnyte's file API: bad names cut big uploads off, and a move onto an existing file merges it
Egnyte rejects file names with Windows-reserved characters, but its API doesn't say so. Small uploads get a 409 that the docs reserve for name clashes; uploads of 4 MB or more have the connection cut mid-transfer, so the client sees a network error. Separately, moving a file onto an existing file returns 200 and folds both into one version history, and the newer one wins.
Ryan McMillan · Found Oct 20, 2026 · Published Oct 22, 2026
Affected
- Service
- Egnyte Public API v1, path-based endpoints (/pubapi/v1/fs-content, /pubapi/v1/fs)
- Account
- One Egnyte business domain, tested October 22, 2026
- Client
- Rust, reqwest 0.13.5 (for the cut-off uploads)
- Names
- Any file name containing " : < > | * ? or \
01
What happens
Egnyte doesn't allow file names with the Windows-reserved characters " : < > | * ? \. Its help desk says so for the desktop and migration apps. The API documentation doesn't list them, and the API doesn't return a clear error when you send one:
- A small upload (
POST /pubapi/v1/fs-content/...) gets 409 Conflict. The API docs give 409 as "file or folder with the same name already exists", so it reads as a clash with a file that isn't there. - An upload of about 4 MB or more never gets a status at all. About three seconds in, the connection is closed while the client is still sending, and the client reports a transport failure. A correctly named 20 MB file took 14 seconds to upload on the same connection, so the server is ending the request early, not timing out.
- A backslash is rejected earlier. Even a metadata lookup (
GET /pubapi/v1/fs/...) for that name returns 400.
A dropped connection is what a flaky network looks like, so a backup job sensibly stops or retries, and retrying never helps. Mine stopped two nights in a row on a 5.9 GB video whose name contained a double quote, while files of 5.6 GB with ordinary names uploaded fine.
Move onto an existing file. POST /pubapi/v1/fs/<source> with {"action":"move","destination":"<existing file>"} returns 200. It doesn't refuse and it doesn't simply overwrite. The source disappears and becomes part of the destination's version history, and whichever file is newer becomes the current version. If the file you moved is older than the one already there, the move "succeeds" but its content survives only as a previous version. If it's newer, it looks like an overwrite.
Quota headers. X-Accesstoken-Quota-Current is documented as the queries per day you've used, but each call type counts separately. A user-info call and a folder listing each report their own running total, so the header from one call doesn't show your total for the day.
02
Evidence
Each size was uploaded twice under a name containing a double quote. The same pattern held for a colon. A test build of my client recorded why each write failed. Nothing was stored for any of the failures:
size result time
1 MB 409 Conflict 3.4 s
2 MB 409 Conflict 3.4 s
3 MB 409 Conflict 3.6 s, 3.0 s
4 MB transport failure while sending the body 3.3 s, 2.7 s
5 MB transport failure while sending the body 3.2 s
10 MB transport failure while sending the body 2.9 s
20 MB transport failure while sending the body 4.0 s, 3.2 s
200 MB transport failure while sending the body
20 MB, ordinary name: uploaded, checksum verified 14.1 sTwo moves onto an existing file, read back with GET /pubapi/v1/fs/<path>:
older source -> newer destination move: 200
current version: destination's content (16 bytes, 01:53:03 GMT)
versions[0]: the moved file (18 bytes, 01:53:00 GMT)
newer source -> older destination move: 200
current version: the moved file (15 bytes, 01:54:15 GMT)
versions[0]: destination's content (13 bytes, 01:54:07 GMT)
num_versions: 2 in both casesFor the quota headers, alternating calls returned user-info counts of 2 then 3 while folder listings in between returned 1, 2 and 3.
03
Reproduce
- 01Create a 1 MB file and a 10 MB file, and upload each to a test folder as
a"b.bin(the quote URL-encoded as%22). The 1 MB upload gets 409. The 10 MB upload ends with a connection reset or closed connection instead of a status. - 02Upload the 10 MB file again under an ordinary name. It succeeds, which rules out size and network.
- 03Upload
old.txt, wait a few seconds, then uploadnew.txt. Moveold.txtontonew.txtwith{"action":"move","destination":"/<folder>/new.txt"}. You get 200 andold.txtis gone. - 04Download
new.txt: it still has its own content.GET /pubapi/v1/fs/<folder>/new.txtshowsnum_versions: 2, withold.txt's content underversions.
04
Fix and cautions
- Clean names before uploading. Egnyte's Migration App replaces each reserved character with an underscore. I map
"to',:to-and the rest to_. Egnyte's help desk lists more rules (no trailing period, no leading or trailing spaces, no control characters, no 4-byte Unicode) that I haven't tested through the API. - If the same file fails with a network error every time while others upload fine, check its name before blaming the network.
- Before a move, look up the destination. Go ahead only if it returns 404, or re-check
num_versionsafterwards. If you need a true overwrite, upload to the destination and then delete the source. - Count your own API calls rather than budgeting from
X-Accesstoken-Quota-Current.
05
Not tested
- One Egnyte business domain, tested on October 22, 2026, with path-based v1 endpoints only. I haven't tested the v2 endpoints, ID-based moves, folder moves or chunked uploads.
- The cut-off happened between 3 and 4 MB on one home internet connection. The exact point probably depends on buffering, and other HTTP clients may still read the 409 when the server answers early. I haven't tested curl or Python.
- I didn't set
Last-Modifiedon uploads, so upload time and modification time were the same. I don't know which one decides the current version after a move. - I saw the quota counters split between user-info and folder-listing calls only. I haven't tested whether the daily cap applies to each counter or to the total.
06
Prior work checked
- Egnyte Help Desk: Unsupported characters and file typesLists the reserved characters and naming rules, and notes the Migration App can replace them. Nothing on API responses.
- Egnyte API: File SystemDefines 409 as a name clash. The move section doesn't say what happens when the destination exists.
- Egnyte API: Best PracticesDescribes X-Accesstoken-Quota-Current as a single daily count.
- One: Egnyte file or folder operation (v1)A third-party API reference that says a move returns 409 when something already exists at the destination. I got 200 and a version merge.
Know of earlier write-ups? Tell me and I'll credit them here.
Updates
- Oct 22, 2026Published.