SparkBox/Guides/Jellyfin index.html

Jellyfin web UI is broken after a script tried to inject into index.html

Your Jellyfin login screen renders half-broken, styles or scripts don't load, or the page shows odd fragments — and when you open index.html you find stray </head> tags scattered through it. The one-line gist: a patch script tried to add JavaScript to index.html using sed, and sed's special handling of the & character silently corrupted the file.

Jellyfin home screen on a SparkBox server
Jellyfin home screen on a SparkBox server

Rather not hand-fix this? SparkBox ships Jellyfin with no index.html injection at all, so this corruption class can't happen — and it self-heals the web files on update. See the walkthrough →

The 10-second version: Stop whatever script is editing index.html, then restore a clean copy of the file (reinstall or update Jellyfin, or replace it from a good backup). The corruption came from a sed injection where every && in the payload was rewritten as </head></head>.

What actually went wrong

Some Jellyfin setups add custom JavaScript or CSS by editing the main web page, index.html — the static HTML file the server hands to your browser when you open Jellyfin. This is the file that pulls in Jellyfin's scripts and styles.

A common but fragile way to do that is with sed, a Linux "stream editor" that finds and replaces text in files. The trap: in a sed replacement string, the ampersand character (&) is special. It doesn't mean a literal ampersand — it expands to whatever text the search pattern just matched.

The injector we diagnosed passed its JavaScript payload straight into that replacement position. JavaScript uses && constantly — it's the logical "and" operator. So every && in the payload got expanded by sed, and because the surrounding match involved the page's </head> tag, each one landed in the file as </head></head>.

Two things happened at once, and both are bad:

This was confirmed on the bench across three separate patch-queue incidents and reproduced on Jellyfin 10.11.1. The version number is not the culprit — the sed injection is. The fix we shipped was to retire the patch-jellyfin-html step entirely and clean the corruption debris off every affected machine.

Step 1 — Confirm it's this problem

Before changing anything, verify the file is actually corrupted so you don't chase the wrong issue.

  1. Find your Jellyfin web root. On many Linux package installs this is /usr/share/jellyfin/web/; Docker images and other platforms differ, so check where your install serves its web files from before touching anything.
  2. Search index.html for stray closing-head tags. A clean Jellyfin page has exactly one </head>. Count them:
    grep -o '</head>' /usr/share/jellyfin/web/index.html | wc -l
    If the result is more than 1, the file is corrupted.
  3. Look at the corruption directly:
    grep -n '</head></head>' /usr/share/jellyfin/web/index.html
    Any match is a smoking gun for the && expansion described above.

Gotcha: A hard-refresh in the browser (Ctrl+F5 / Cmd+Shift+R) can hide or reveal the symptom because of caching. Always judge from the file on disk, not the rendered page.

Step 2 — Stop the thing that edits index.html

This is the most important step. If you restore a clean file but leave the injector running, the next time it fires it will corrupt the fresh copy again — and you'll be back here.

  1. Identify what modifies index.html on your system. Likely candidates: a "custom JS/CSS" helper script, a themer/plugin installer, a post-update hook, or a cron job. Search your setup scripts for index.html and for sed.
  2. Disable or remove that step. If it's a scheduled job, comment it out. If it's a container entrypoint or init hook, remove the injection line.
  3. If you genuinely need custom JavaScript, do not re-add it via a raw sed replacement. See the safer approaches in Step 4.

Step 3 — Restore a clean index.html

You have three good options. Pick whichever matches your setup.

Option A — Reinstall or update Jellyfin's web files (cleanest)

Jellyfin's web assets ship with the application. Reinstalling or updating the package or container replaces index.html with a pristine copy. This is the most reliable fix because you get the exact file that matches your Jellyfin version — no guessing.

After it completes, re-run the grep from Step 1. The count should be exactly 1.

Option B — Restore from a backup

If you back up your Jellyfin install, copy a known-good index.html from before the injection back into the web root. Make sure the backup predates the corruption — restoring a file that already has the stray </head> tags gets you nowhere.

Option C — Edit the file by hand (last resort)

If you can't reinstall right now, you can repair the file directly. Back it up first, then open it in a text editor and:

  1. Delete the entire dead injected block (the broken script you or the tool added).
  2. Remove every extra </head> so exactly one remains, in its correct place just before <body>.
  3. Save and hard-refresh the browser.

Gotcha: Hand-editing is fragile because you're reconstructing what the file should look like. If you're not confident about HTML structure, prefer Option A — a reinstall removes all doubt.

Step 4 — If you still want custom JavaScript, do it the safe way

The reason to move away from sed is exactly what caused this bug: sed treats several characters (&, \, and your chosen delimiter) as special, so any real-world JavaScript payload is a landmine. Safer paths:

Frequently asked

Why does my Jellyfin index.html have extra </head> tags in it?

A script tried to inject JavaScript into index.html using sed, where the ampersand (&) is a special character that expands to the matched text. Any && in the payload was rewritten as </head></head>, salting the file with stray closing-head fragments and breaking the page.

Will updating Jellyfin fix a corrupted index.html?

Usually yes. A Jellyfin update or reinstall replaces the web files, including index.html, with clean copies from the package. But if your injector runs again after the update, it will re-corrupt the fresh file — so retire or fix the injector first (Step 2).

Is it safe to edit Jellyfin's index.html by hand?

Yes, if you back it up first. index.html is a static web asset. Remove the stray </head></head> fragments and any dead injected block, save, then hard-refresh. Restoring the packaged copy is the cleaner option if you're unsure.

Does this affect Jellyfin 10.11.1?

The corruption class was reproduced and confirmed on Jellyfin 10.11.1. The version is not the cause — the sed-based injection is. Any Jellyfin build served the corrupted index.html shows the same broken UI.

Skip the index.html surgery entirely

SparkBox runs Jellyfin without any sed injection into index.html, so this corruption class simply can't occur — and its updates restore clean web files for you.

Get SparkBox → Or read the media-server walkthrough →

About this guide: Written and tested by the SparkBox team on a UGREEN DXP4800 Plus and a $7/month Hostinger VPS, both running SparkBox 1.6.424. The causes above are the real ones we've diagnosed in d/sparkbox. If something doesn't match, tell us on YouTube.