Backup restore/upload rejects valid `.tar` with "Unsupported file format" on Firefox for Windows (client-side File.type/MIME validation)
### Checklist
- [x] I have updated to the latest available Home Assistant version.
- [x] I have cleared the cache of my browser.
- [x] I have tried a different browser to see if it is related to my browser.
- [ ] I have tried reproducing the issue in [safe mode](https://www.home-assistant.io/blog/2023/11/01/release-202311/#restarting-into-safe-mode) to rule out problems with unsupported custom resources.
### Describe the issue you are experiencing
Selecting a valid Home Assistant `.tar` backup for restore/upload in **Firefox on Windows** is rejected with the popup:
> Unsupported file format – Please choose a Home Assistant backup file (.tar)
This happens both during onboarding ("Alternatively you can restore from a previous backup") and via Settings → System → Backups → Upload backup. The same file works in Chromium-based browsers (Chrome/Edge), and it restores fine if placed directly into the backup folder (e.g. via Samba/SSH), which rules out the file and the backend — the rejection is purely client-side in the upload dialog.
This is a long-standing, still-unresolved problem. The direct frontend report (#12895) was **closed as stale without a fix**, even though a user there already identified the likely MIME cause back in 2022. The original cross-posted report (home-assistant/supervisor#3639) is **locked and in the wrong repository**. I have re-verified this is **still reproducible on current versions** (see Environment below). The download-side Firefox/Workbox issue (#7258) is a *separate* bug and not the cause here.
### Describe the behavior you expected
A valid `.tar` backup is accepted in Firefox on Windows, identical to Chromium.
### Steps to reproduce the issue
1. On Firefox for Windows, open Home Assistant (onboarding restore screen or Settings → System → Backups → Upload backup).
2. Select a valid `.tar` backup produced by Home Assistant.
3. The "Unsupported file format" popup appears immediately, before any upload starts.
4. Repeat the exact same steps in Chrome/Edge → the file is accepted.
### What version of Home Assistant Core has the issue?
2026.6.2
### What was the last working version of Home Assistant Core?
_No response_
### In which browser are you experiencing the issue?
Firefox 151.04
### Which operating system are you using to run this browser?
Windows 10
### State of relevant entities
```txt
```
### Problem-relevant frontend configuration
```yaml
```
### JavaScript errors shown in your browser console/inspector
```txt
```
### Additional information
### Root cause analysis
This is a client-side validation problem, not a backend one (the same file restores fine when placed directly into the backup folder). The browser/OS pattern is the key signal:
| Browser / OS | Result |
|--------------------------|---------------------------------------------------------------------------------------------------------------|
| Firefox / Windows | rejected (many reports) |
| Firefox / Linux | accepted (one report in home-assistant/supervisor#3639, FF 108; independently consistent with the OS-level mechanism below) |
| Chrome / Edge (Chromium) | accepted (many reports) |
An extension-only check would behave identically across browsers, so the fact that only Firefox-on-Windows fails is the fingerprint of a check that gates on the file's **MIME type** (`File.type`) rather than its extension.
Why `File.type` differs:
- `.tar` has no IANA-registered MIME type; the de-facto value is `application/x-tar`.
- For a file chosen via `<input type="file">`, the browser derives `File.type` from OS-level MIME sources, and per the spec it is the **empty string** when the type can't be determined. MDN explicitly warns this happens for uncommon extensions, that the Windows Registry can affect the result, and that `File.type` must not be used as a sole validation scheme:
https://developer.mozilla.org/en-US/docs/Web/API/Blob/type
- **Firefox on Windows** resolves the type via the OS/registry (`HKEY_CLASSES_ROOT\.tar` → "Content Type"). Windows has no default `.tar` association, so `File.type` is `""`. Exactly this behavior is documented for `.zip` in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1681924
- **Firefox on Linux** resolves the type via the freedesktop `shared-mime-info` database, which knows `.tar` → `application/x-tar`, so `File.type` is populated. The Windows-only nature of empty/incorrect `File.type` in Firefox is independently reported for `.csv` as well (works on Linux, fails on Windows).
- **Chromium (Chrome/Edge)** ships a built-in extension→MIME table that is consulted before the registry, so it returns `application/x-tar` for `.tar` regardless of OS.
So whenever the validation requires a non-empty / allow-listed MIME type, Firefox-on-Windows fails because `File.type === ""`. This explains every row of the matrix and the "direct file placement works" data point.
Note: returning `""` here is spec-compliant browser behavior, so this is **not** an upstream Firefox bug to fix — the defect is relying on `File.type` for `.tar` validation at all.
(I have not pinpointed the exact validation line in the current source; maintainers can confirm whether the upload/restore path checks `File.type`/MIME. Likely locations: `src/onboarding/onboarding-restore-backup.ts`, the upload/restore dialogs under `src/panels/config/backup/`, and `src/components/ha-file-upload.ts`.)
### Proposed fix
Do **not** gate on `File.type` at all — it is unreliable by design (empty or registry-dependent for `.tar`, per MDN). Validate by file **extension** only and let the backend perform authoritative content validation (it already does; that is why placing the file directly into the backup folder works):
*(Illustrative — I have not located the exact line in the current source; the snippets show the suspected pattern, not quoted code.)*
```ts
// BEFORE — rejects whenever File.type isn't exactly application/x-tar
// (empty on Firefox/Windows, and registry-dependent in general)
if (!["application/x-tar"].includes(file.type)) { /* show "unsupported" */ }
// AFTER — extension-only; tolerant of any/empty MIME
if (!file.name.toLowerCase().endsWith(".tar")) { /* show "unsupported" */ }
```
Additionally, set the file input to filter by extension rather than MIME, so the picker pre-selects correctly on all browsers/OSes:
```html
<!-- prefer extension-based accept over a MIME-based one -->
<input type="file" accept=".tar" />
```
Optional hardening (not required for the fix): instead of trusting the extension, sniff the tar magic bytes client-side — a POSIX tar has the ASCII marker `ustar` at byte offset 257 — to give an early, browser-independent "this isn't a backup" message. The extension-only change above is the minimal correct fix; the backend remains the real validator.
关闭于 2026-06-19 0 条评论