Skip to Content
Dispatcharr

Dispatcharr

Self-hosted IPTV proxy with M3U/EPG management, transcoding, and DVR

Dispatcharr is a self-hosted IPTV proxy server that merges multiple M3U playlists and Xtream Codes accounts into a single channel lineup with rich EPG matching, FFmpeg-based transcoding, and HDHomeRun emulation for Plex, Emby, and Jellyfin. QuickBox Pro installs Dispatcharr per user with an isolated PostgreSQL cluster, dedicated Redis broker, Gunicorn HTTP server, Daphne WebSocket server, and Celery worker plus beat scheduler — all on auto-allocated ports proxied under the per-user nginx vhost. Each user is the administrator of their own Dispatcharr instance.


Key features

M3U and Xtream Codes Ingest

Import unlimited playlists and credential-based providers with deduplication and channel mapping

EPG Matching

XMLTV and Xtream EPG support with fuzzy matching, manual overrides, and per-channel program metadata

FFmpeg Transcoding

Output profiles for resolution, bitrate, audio codec, and container format with hardware acceleration support

HDHomeRun Emulation

Native tuner discovery for Plex, Emby, and Jellyfin so Live TV works without a physical capture card

VOD with Metadata

Movie and series catalog with IMDb and TMDB poster, plot, and rating enrichment

Stream Proxy and Relay

Buffered relay reduces upstream provider load and stabilizes playback across clients

DVR and Recordings

Schedule recordings against EPG entries with disk-aware retention and per-user storage isolation

Per-User Stack

Isolated PostgreSQL, Redis, Gunicorn, Daphne, and Celery services so each QuickBox user owns their data

Each user is fully isolated

Every QuickBox user who installs Dispatcharr gets their own database, Redis broker, application services, EPG data, and DVR storage. Users do not share channel lineups, accounts, or recordings.


When to use it

Symptoms

  • You have one or more IPTV providers with M3U or Xtream Codes credentials
  • You want Live TV inside Plex, Emby, or Jellyfin without a physical tuner
  • You need EPG (program guide) data merged from multiple sources
  • You want to record live channels with DVR support
  • You want to transcode streams for lower-bandwidth clients

Resolution

  • Install via qb install dispatcharr -u username
  • Add M3U or Xtream credentials in the web UI
  • Configure XMLTV or Xtream EPG sources and let Dispatcharr match channels
  • Point Plex, Emby, or Jellyfin Live TV at the built-in HDHomeRun tuner
  • Configure transcoding profiles per channel as needed

Installation

First install requires an admin

The first Dispatcharr install on the server must be performed by a QuickBox admin (a user with user_level >= 9 — either the super admin who owns the box, or an admin-tier user). That first install primes the host with the shared system dependencies (PostgreSQL, Redis, FFmpeg) and disables any server-wide PostgreSQL or Redis service so each user can run their own isolated cluster. After any admin has completed that first install once, every QuickBox user can install their own per-user Dispatcharr instance without admin involvement — subsequent installs skip the system-level setup and only provision the per-user stack.

Install from the QuickBox CLI

Install Dispatcharr for a specific user under the per-user subpath:

qb install dispatcharr -u username

Install and publish on a dedicated subdomain in one call — this issues the Let’s Encrypt certificate and writes the subdomain nginx vhost as part of the install:

qb install dispatcharr -u username -d dispatcharr.example.com

Install the development branch (latest upstream features, less stable):

qb install dispatcharr -u username --beta

CLI commands

CommandDescription
qb install dispatcharr -u usernameInstall Dispatcharr stable branch under the per-user subpath
qb install dispatcharr -u username -d <domain>Install Dispatcharr and publish it on a dedicated subdomain with SSL in one call
qb install dispatcharr -u username --betaInstall Dispatcharr development branch
qb reinstall dispatcharr -u usernameReinstall Dispatcharr — wipes and rebuilds the per-user database, runtimes, and credentials
qb update dispatcharr -u usernameUpdate Dispatcharr in place — rebuilds Python venv and frontend, preserves the database
qb remove dispatcharr -u usernameRemove Dispatcharr, its data, and the per-user PostgreSQL and Redis services
qb help dispatcharrDisplay help information

Install flags

FlagDescription
-u <username>Target QuickBox user for the per-user install (required)
-d <domain>Install in subdomain mode — issues SSL, writes the subdomain vhost, and rebuilds the frontend for root
--betaInstall the upstream dev branch instead of main
-vVerbose output (used by the dashboard to stream live install logs)
-fForce flag forwarded to the dispatcher
-hPrint help

Install from the Dashboard

You can also install Dispatcharr from the QuickBox Pro dashboard. The dashboard installs Dispatcharr for the currently signed-in user — there is no user picker on the install dialog. To install Dispatcharr for a different user, use the CLI with an explicit -u <other_user>.

To install from the dashboard:

  1. Open App Dashboard → Package Management (/dashboard?mode=packages)
  2. Find Dispatcharr under the Media Servers category
  3. (Optional) Choose Beta for the development branch
  4. (Optional) Switch the Custom Domain toggle to Custom and enter a domain — the install will issue SSL and publish on that subdomain
  5. Submit — a live install log streams in the response modal

The dashboard runs the same install pipeline as the CLI.

Automatic port assignment

QuickBox picks a free external HTTP port near the upstream default of 9191 and derives four internal ports (Gunicorn, Daphne, PostgreSQL, Redis) from it with collision-avoidance. The external port is recorded in the QuickBox database — you can find it on the Dispatcharr row in the dashboard’s App Dashboard. The internal ports are listed in the per-user systemd unit files and do not need to be touched.


Architecture

Each QuickBox user gets a fully isolated Dispatcharr stack made up of six systemd services:

ServiceRole
postgresql@usernamePer-user PostgreSQL cluster (binds 127.0.0.1 only)
redis@usernamePer-user Redis broker (binds 127.0.0.1 only, AOF persistence)
dispatcharr-gunicorn@usernameWSGI HTTP server — serves the Dispatcharr web UI and REST API
dispatcharr-daphne@usernameASGI WebSocket server — handles live UI updates
dispatcharr-celery-worker@usernameBackground worker — fetches playlists, EPG data, and stream metadata
dispatcharr-celery-beat@usernameScheduler — triggers periodic refresh tasks

The four Dispatcharr application services depend on the per-user PostgreSQL and Redis services and start in dependency order at boot. The nginx vhost proxies HTTP traffic to Gunicorn and WebSocket traffic to Daphne under the same per-user path.


Access and authentication

URL

Dispatcharr is published under the per-user subpath of your QuickBox dashboard:

https://your-server/username/dispatcharr/

The WebSocket endpoint that powers live UI updates is:

https://your-server/username/dispatcharr/ws/

You can also click Open on the Dispatcharr row in the dashboard’s App Dashboard to launch the UI directly. When Dispatcharr is published on a custom subdomain (see Custom subdomain with SSL below), the Open link points at https://<your-subdomain>/ instead.

First-run setup

Each QuickBox user is the administrator of their own Dispatcharr instance — every user installs Dispatcharr into their own per-user stack and gets their own superuser account. The Dispatcharr admin account is provisioned automatically at install time; see Accessing your admin account below for how to retrieve the auto-generated password before your first login.

  1. Retrieve your admin credentials (see the section below)
  2. Open the per-user URL above and sign in
  3. Add an M3U or Xtream Codes source under Playlists
  4. Add an XMLTV or Xtream EPG source under EPG
  5. Map channels and configure transcoding profiles as needed
  6. Point Plex, Emby, or Jellyfin Live TV at the Dispatcharr HDHomeRun endpoint

Accessing your admin account

QuickBox provisions a Dispatcharr superuser at install time so you can log in immediately. The username matches your QuickBox account, and the password is randomly generated (24 alphanumeric characters) and written to a credentials file on disk. Upstream Dispatcharr does not expose a first-user setup wizard on the login page — without these credentials the UI rejects every sign-in attempt.

From the QuickBox dashboard (preferred)

  1. Open the App Dashboard (/dashboard) in QuickBox Pro
  2. Find the Dispatcharr row for your user and expand it
  3. The expansion panel surfaces the admin Username and a click-to-reveal Password in the API & Secrets section
  4. Copy the password and paste it into the Dispatcharr login form

The dashboard reads the credentials file over a privileged backend call — the password is never embedded in the page source, and it stays masked until you explicitly reveal it. The endpoint is owner-self or admin-tier only: another non-admin user cannot read your Dispatcharr password through the dashboard.

From the server over SSH (fallback)

If you have not loaded the dashboard yet, you can read the credentials file directly:

# As your QuickBox user cat ~/.config/dispatcharr/.admin_credentials # Or, with sudo, from any account sudo cat /home/username/.config/dispatcharr/.admin_credentials

The file uses a simple key=value format:

username=username password=auto-generated-password
File ownership and permissions

The credentials file is created with mode 0640 owned username:qbusers. The owning user has read and write access, the qbusers group (which includes the dashboard backend service account) has read-only access, and no other user can read it. On older installs created before this change, the file may be 0600 username:username — a qb reinstall dispatcharr -u username brings it to the current scheme.

Rotate after first login

Treat the auto-generated password as a bootstrap credential. After your first successful login, sign in to Dispatcharr, open your account page, and change the password to something you control. Update the credentials file by hand (or leave it stale) once you have rotated — Dispatcharr does not write back to it.


Custom subdomain with SSL

By default Dispatcharr serves under the per-user subpath of your main dashboard domain. You can also publish it on a dedicated subdomain (for example dispatcharr.example.com) with a Let’s Encrypt certificate. There are three ways to set this up: a single-call install (Path A), a post-install retrofit from the CLI (Path B), and the dashboard SSL Control page (Path C).

QuickBox ships a managed nginx template for the Dispatcharr subdomain reverse proxy. The template handles:

  • HTTPS on port 443 with HTTP/2
  • Cloudflare real-IP support (when configured)
  • WebSocket upgrades on the /ws/ location for live UI updates
  • Static asset serving directly from the per-user install tree
  • A 100 MB upload limit for M3U and EPG files
  • gzip compression for text, JSON, and JavaScript

Path A — Subdomain at install time

The fastest path is to pass -d <domain> to qb install dispatcharr. The install builds the React frontend for root, issues the certificate, writes the subdomain vhost, and starts the services in one call — no separate lecert step required.

Point a DNS record (A or CNAME) for your chosen subdomain at the server, then run:

qb install dispatcharr -u username -d dispatcharr.example.com

The install chain-calls Let’s Encrypt under the hood and auto-detects any saved DNS provider credentials from /root/.acme.sh/account.conf (Cloudflare, Route 53, DigitalOcean, GoDaddy, Namecheap, Linode, OVH, Vultr, Gandi, DNSimple, Hurricane Electric, Azure, GCP, and IONOS are detected automatically and switched to the appropriate DNS challenge).

When to use Path A vs Path B

Use Path A when you know the subdomain you want before installing. The install builds the frontend correctly for the subdomain on the first try and you never see the subpath URL. Use Path B when Dispatcharr is already running on the per-user subpath and you want to move it to a subdomain.

Path B — Retrofit a subdomain to an existing install

If Dispatcharr is already installed and you want to move it to a dedicated subdomain, issue the certificate with the Dispatcharr-specific lecert flag:

qb install lecert --dispatcharr -d dispatcharr.example.com -u username

This uses the same shape as every other lecert-managed application (--emby, --jellyfin, --plex, --komga, etc.). QuickBox:

  1. Requests a Let’s Encrypt certificate for the supplied domain (HTTP-01 challenge by default)
  2. Resolves the deployed Gunicorn and Daphne ports from the per-user systemd units
  3. Writes the subdomain template into /etc/nginx/sites-enabled/dispatcharr.<domain> with the right ports filled in
  4. Stops the four Dispatcharr application services, rebuilds the React frontend for root, and restarts them
  5. Reloads nginx and registers the certificate for automatic renewal

Wildcard or DNS challenge: add --dns --dns-provider cloudflare (or another supported provider) and use a wildcard domain such as *.domain.com. See the Let’s Encrypt application reference for the full list of supported DNS providers.

Testing without rate-limit exposure: add --staging to issue against the Let’s Encrypt staging CA, or --dry-run to validate the ACME challenge without writing any certificate or nginx changes. Combine the two to fully exercise the flow with zero side effects.

Removing the subdomain: qb ssl-remove lecert --dispatcharr -d <domain> -u username deletes the subdomain vhost. If Dispatcharr is still installed, the remove rebuilds the frontend for the per-user subpath URL so subpath access continues to work.

Path C — Dashboard SSL Control

The dashboard’s SSL Control page at System → SSL Control (/system/ssl) exposes the same flow. The form fields, in order, are:

  1. Target — pick Dispatcharr from the dropdown
  2. Domain — your chosen subdomain (for example dispatcharr.example.com)
  3. Challenge Method — HTTP-01 (the default) or DNS-01
  4. DNS Provider — only shown when DNS-01 is selected (Cloudflare, Route 53, GoDaddy, Namecheap, DigitalOcean, Linode, OVH, Vultr, Gandi, DNSimple, Hurricane Electric, Azure, GCP, IONOS)
  5. DNS credentials — only shown when DNS-01 is selected and no credentials are saved for that provider yet
  6. Username — required for Dispatcharr; this is the QuickBox user that owns the install

The SSL Control page runs the same qb install lecert --dispatcharr pipeline under the hood.

See the SSL Control page

For end-to-end SSL setup, supported DNS providers, wildcard certificates, and renewal behavior, see the SSL Certificates dashboard page and the Let’s Encrypt application reference.


VPN routing

Dispatcharr can route all of its upstream traffic through a WireGuard VPN tunnel using QuickBox Pro’s app-scoped routing. When routing is enabled, every upstream egress path — Gunicorn-proxied streams, Daphne WebSocket relays, Celery worker playlist and EPG fetches, and Celery beat scheduler triggers — exits through the same VPN peer. PostgreSQL and Redis stay on the host because they bind localhost only and do not emit upstream traffic.

How to enable VPN routing for Dispatcharr:

  1. Go to System → VPN Control (/system/vpn) in the dashboard
  2. Upload at least one WireGuard .conf file if you have not done so already
  3. Scroll to the App-Scoped Routing card on the VPN Control page
  4. Select Dispatcharr from the app list
  5. Choose a WireGuard peer configuration from the dropdown
  6. Click Enable Routing

The four Dispatcharr application services restart inside the VPN network namespace (qb_dispatcharr). Upstream IPTV providers and EPG sources will see the VPN exit IP from that point forward.

Multi-service routing is automatic

You do not need to enable routing for each Dispatcharr service individually. QuickBox treats the four Dispatcharr application services as a single routable group and moves them into one shared network namespace together. PostgreSQL and Redis stay outside the namespace by design — they bind localhost (and a per-user Unix socket) only and do not need to follow the VPN.

The default kill-switch stale threshold for Dispatcharr is 30 minutes, matching qBittorrent — IPTV workloads include long DVR sessions and recurring EPG fetches, so a shorter window risks tearing down routing during legitimate gaps in upstream activity. You can adjust it on the app row inside the App-Scoped Routing card.

For full details on routing configuration, kill switch settings, and live metrics, see the VPN Control dashboard page.


How to: connect Dispatcharr to Plex

This is the end-to-end guide for turning Dispatcharr into a Live TV source for Plex, plus the three tools QuickBox provides to keep Plex’s TV guide correct. If you use Emby or Jellyfin, see Connect Emby and Jellyfin instead — those servers read Dispatcharr’s guide directly and need none of the Plex-specific guide tools below.

Read this first: Plex never reads your XMLTV file directly

The single most common mistake is pointing Plex straight at an XMLTV/EPG guide file (a URL or an uploaded .xml) — Plex rejects it with “EPG/XMLTV invalid or missing file”. That is expected: Plex does not consume your guide file at all. You configure your M3U playlist and your XMLTV/Xtream EPG source inside Dispatcharr. Dispatcharr fetches, caches, and matches that guide, then exposes the whole lineup — channels and guide — through its emulated HDHomeRun tuner. Plex only ever talks to that tuner at https://your-server/username/dispatcharr/hdhr . Do the Dispatcharr-side setup in Step 1 first; only then add the tuner to Plex in Step 2.

The connection order is always the same:

  1. In Dispatcharr — add your M3U/Xtream source and your XMLTV/Xtream EPG source, then let Dispatcharr match channels (Step 1).
  2. In Plex — add Dispatcharr’s HDHomeRun tuner by URL; Plex reads the channels and guide from the tuner (Step 2).
  3. Optional guide tools — three QuickBox helpers keep Plex’s native guide and channel map correct over time (Step 3).

Step 1 — Set up your sources inside Dispatcharr (not in Plex)

Everything about your channels and your program guide is configured in Dispatcharr’s own web UI. This is where the guide file goes — never into Plex.

  1. Open Dispatcharr at https://your-server/username/dispatcharr/ and sign in
  2. Go to Playlists → Add Playlist and add your M3U URL or Xtream Codes credentials — Dispatcharr fetches the playlist and lists the channels
  3. Go to EPG → Add EPG Source and add your XMLTV URL or Xtream EPG endpoint — this is the guide file, and it belongs here in Dispatcharr, not in Plex
  4. Dispatcharr fetches the EPG and matches it against your channel list; use Manual Match for any channel that did not auto-match
  5. (Optional) Edit channel names, numbers, and group assignments under Channels

Once Dispatcharr is fetching the playlist and the EPG, both the channel lineup and the program guide are ready to serve over the HDHomeRun tuner. The QuickBox dashboard already shows the correct guide at this point — you can verify your channels and programs there before involving Plex at all.

100 MB upload limit for M3U and EPG files

If you upload an M3U or XMLTV file directly to Dispatcharr (instead of giving it a URL), QuickBox’s nginx allows files up to 100 MB. A larger upload is rejected by the proxy before it reaches Dispatcharr. For very large playlists or guides, prefer a source URL so Dispatcharr fetches it server-side with no upload-size limit.

Step 2 — Add the Dispatcharr tuner in Plex

With your sources configured in Dispatcharr, you now point Plex at Dispatcharr’s emulated tuner. Dispatcharr exposes an HDHomeRun-compatible (HDHR) tuner that carries both the channel lineup and the guide — Plex’s Live TV & DVR feature tunes it just like a physical capture card. The tuner is published at the /hdhr path under your Dispatcharr URL:

https://your-server/username/dispatcharr/hdhr

When Dispatcharr is published on a dedicated subdomain, the tuner URL is https://dispatcharr.example.com/hdhr.

  1. In Plex, open Settings → Live TV & DVR → Set up Plex DVR
  2. When Plex cannot find a tuner automatically, click Don’t see your HDHomeRun device? / Enter its network address manually
  3. Enter the Dispatcharr HDHR URL (subpath or subdomain form above) — this is the only address Plex needs; do not paste an XMLTV/guide URL here
  4. Plex reads the channel lineup from the tuner — map the guide and select the channels to expose
  5. Finish the DVR setup and start watching Live TV
AC3 audio is already configured for you

Plex’s bundled FFmpeg cannot copy AAC audio into its Live TV segmenter — a Dispatcharr channel with AAC audio fails to tune with “Could not tune channel.” QuickBox seeds an output profile named Plex HDHR (transcode) (video copied, audio re-encoded to AC3 48 kHz stereo) and binds it as the HDHR default on every install, reinstall, and update — so Plex tunes Dispatcharr channels out of the box. The seeding is idempotent and never overwrites a profile you bound yourself. See Plex says “Could not tune channel” for the full explanation.

Which URL do I give Plex?

The address you enter in Plex depends on where Plex itself is running. In every case the path ends in /hdhr, but the host and port differ:

Where Plex runs
On a different device (another computer, NAS, or off the server entirely) — the usual case
Tuner URL to enter in Plex
https://your-server/username/dispatcharr/hdhr (subpath) or https://dispatcharr.example.com/hdhr (subdomain)
Where Plex runs
On the same QuickBox server as Dispatcharr (a local / home install with Plex on the box)
Tuner URL to enter in Plex
http://127.0.0.1:<PORT>/hdhr, where <PORT> is the main application port shown on the Dispatcharr row in the App Dashboard
If Plex runs on the same QuickBox server (local / home install)

When Plex is installed on the same box as Dispatcharr, you may point Plex straight at Dispatcharr over the loopback address instead of going through nginx:

http://127.0.0.1:<PORT>/hdhr

<PORT> is the port shown on the Dispatcharr row in the App Dashboard — this is the main Dispatcharr web application port (Gunicorn). To find it, open the App Dashboard, locate the Dispatcharr row, and read the port displayed on the row itself.

Use the row port, not the Daemon port

Expanding the Dispatcharr row shows an additional Daemon port. That is Dispatcharr’s WebSocket service (Daphne), which powers live UI updates — it is not the tuner and Plex cannot use it. Always use the port shown on the Dispatcharr row (the main web-application port), never the Daemon port from the expansion panel.

A LAN-IP-plus-port tuner URL can never work

Dispatcharr’s internal services bind to 127.0.0.1 (loopback) only. A tuner URL built from the server’s LAN IP and a raw port — for example http://192.168.x.x:<port>/hdhrcan never reach Dispatcharr, even on your own home network, and Plex will fail to add the tuner. There are only two URLs that work: the same-box loopback URL above (http://127.0.0.1:<PORT>/hdhr) when Plex is on the box, or the nginx URL (https://your-server/username/dispatcharr/hdhr subpath, or https://dispatcharr.example.com/hdhr subdomain) when Plex is on any other device. For Plex on a different device, always use the nginx URL form.

Step 3 — Keep Plex’s TV guide correct

Once Plex is tuning Dispatcharr channels, two things commonly drift over time: Plex can tune the wrong channel after you renumber your Dispatcharr lineup, and Plex’s program guide can show the wrong show. QuickBox provides three tools to keep things correct, all available from both the QuickBox dashboard and the qb CLI. The table shows who is authorized to use each — gate by WHO, not by where the action runs.

Tool
EPG override (Base URL + API key)
What it fixes
Corrects Plex's Live TV program guide using Dispatcharr's own EPG data
Who can run it
Admin only
Tool
Channel-map repair (preview → apply)
What it fixes
Plex tuning the wrong channel after a Dispatcharr lineup renumber
Who can run it
The Dispatcharr owner, or any admin-tier user
Tool
Duplicate guide-id scan (report-only)
What it fixes
Finds channels that share a guide id (tvg_id) so the EPG shows the wrong program
Who can run it
The Dispatcharr owner, or any admin-tier user

EPG override (admin only)

By default Plex builds its program guide from its own Gracenote cloud guide, which often mismatches IPTV channels. The EPG override points Plex’s guide at Dispatcharr’s data instead. An admin configures it under Dashboard → Streaming → Settings in the Plex Live TV Guide (Dispatcharr) card:

  1. Open Dashboard → Streaming → Settings
  2. In the Plex Live TV Guide (Dispatcharr) card, enter the Dispatcharr Base URL and API Key
  3. Save — the dashboard now corrects Plex’s Live TV guide from Dispatcharr’s data

On QuickBox Dispatcharr installs this is auto-provisioned — the install generates a Dispatcharr API key for the admin user and wires the override automatically, so the dashboard already shows the correct program for every channel without manual setup. Leave the Base URL blank to fall back to Plex’s built-in Gracenote guide. The API key is write-only — it is never displayed back or written to logs.

The dashboard already shows the correct guide

The QuickBox dashboard reads Dispatcharr’s EPG straight from the source, so it shows the correct channel and program for every channel regardless of Gracenote. This is the recommended way to view accurate Live TV. Correcting Plex’s own native app guide with Gracenote station ids (covered in Troubleshooting) is optional and only works for channels with a real broadcast equivalent.

Channel-map repair (owner or admin-tier)

When you renumber channels in Dispatcharr, Plex’s cached channel map goes stale and it tunes the wrong channel. The channel-map repair re-syncs Plex’s map to your current Dispatcharr lineup. It always previews first — nothing is written until you confirm — and backs up the current map before applying any change.

From the dashboard: open Dashboard → Streaming → Settings, click Re-sync Plex channel map, review the per-channel current → corrected rows, then Apply. The owner of the Dispatcharr install can run this for their own Plex; an admin-tier user can run it for any install.

From the CLI:

# Preview the changes (dry-run — writes nothing) qb manage dispatcharr channelmap --user username # Apply the corrected map (backs up the current map first, then reloads the guide) qb manage dispatcharr channelmap --user username --apply

QuickBox also runs this repair on an automatic schedule (every 8 hours, plus at install and update time), so a stale map usually corrects itself without any action. See Plex tunes the wrong channel after a lineup change for the full breakdown.

Duplicate guide-id scan (owner or admin-tier)

If two different Dispatcharr channels share the same guide id (tvg_id), Plex maps that guide id to only one of them — so the others show the wrong program (or none). The duplicate guide-id scan is a report-only check that finds these collisions. It never changes anything — you fix the duplicates yourself in Dispatcharr by giving each channel a distinct tvg_id.

From the dashboard: open Dashboard → Streaming → Settings and click Check duplicate guide IDs. The scan lists every channel that shares a guide id with another.

From the CLI:

# Report channels that share a guide id (read-only — writes nothing) qb manage dispatcharr dupes --user username

The scan reads only the per-user Dispatcharr database — it never contacts Plex — so it works the same whether or not Plex Live TV is set up. Finding duplicates is a normal, reportable result, not an error.

Clean up leftover or test HDHomeRun tuners

Spinning up a test Dispatcharr instance — or switching HDHomeRun profiles — can leave stale tuners registered in Plex. You can remove them from Dashboard → Streaming → Settings → Plex Tuners, which lists every Plex tuner as active, staged, or orphaned. There, a tuner’s number (e.g. 4) is its concurrent-stream capacity, not a device count. See WSDashboard Settings → Plex Tuners.

Dispatcharr to Plex is the only server that needs these tools

The EPG override, channel-map repair, and duplicate guide-id scan all exist because of how Plex builds its native Live TV guide. Emby and Jellyfin read Dispatcharr’s guide directly, so they always show the correct channel and program with no extra configuration.


Configuration and files

/
opt/username/dispatcharr//# Per-user Dispatcharr source tree (git clone) — Python venv, Django app, and built frontend
├── env//# Python virtualenv (gunicorn, daphne, celery, psycopg2, redis)
├── frontend/dist//# Pre-built React frontend assets served by nginx
└── manage.py# Django management entry point
home/username/.config/dispatcharr//# Dispatcharr configuration directory
├── .env# Environment file — Django secret, database credentials, ports, DISPATCHARR_PLUGINS_DIR (0600, user-owned)
├── .admin_credentials# Auto-generated admin username and password for the Dispatcharr superuser (0640 username:qbusers)
└── dispatcharr_beta.txt# Marker file present when the beta branch is installed
home/username/.local/share/dispatcharr//# Persistent Dispatcharr data
├── logos//# Channel logo cache
├── recordings//# DVR recordings storage
├── uploads/m3us//# Uploaded M3U playlist files
├── uploads/epgs//# Uploaded XMLTV EPG files
├── m3us//# Generated M3U output for downstream players
├── epgs//# Cached EPG data
├── plugins//# User-installed Dispatcharr plugins
└── logs//# Dispatcharr application logs
home/username/.local/lib/postgresql/username/data//# Per-user PostgreSQL cluster data directory
home/username/.local/lib/redis/username//# Per-user Redis working directory (holds dispatcharr.aof persistence file)
etc/nginx/software/username.dispatcharr.conf# nginx subpath configuration for /username/dispatcharr/
etc/systemd/system//# Per-user systemd unit instances
├── postgresql@username.service# Per-user PostgreSQL service
├── redis@username.service# Per-user Redis service
├── dispatcharr-gunicorn@username.service# WSGI HTTP server
├── dispatcharr-daphne@username.service# ASGI WebSocket server
├── dispatcharr-celery-worker@username.service# Background task worker
└── dispatcharr-celery-beat@username.service# Periodic task scheduler
.env contains secrets

The .env file holds Dispatcharr’s Django secret key and PostgreSQL password. QuickBox writes it with 0600 permissions owned by your user. Do not share it, do not commit it to a public repository, and do not change the file mode.


Service management

Every Dispatcharr service is a per-user systemd unit. Replace username with the actual QuickBox username.

# Status — primary HTTP entry point systemctl status dispatcharr-gunicorn@username # Restart the full Dispatcharr stack systemctl restart dispatcharr-gunicorn@username systemctl restart dispatcharr-daphne@username systemctl restart dispatcharr-celery-worker@username systemctl restart dispatcharr-celery-beat@username # Restart the per-user PostgreSQL or Redis (rarely needed) systemctl restart postgresql@username systemctl restart redis@username # Follow live logs for any service journalctl -u dispatcharr-gunicorn@username -f journalctl -u dispatcharr-celery-worker@username -f
Restarting Gunicorn alone does not restart Celery

If you change EPG matching, playlist refresh schedules, or any Celery-side behavior, restart the worker and beat services as well. Restarting only Gunicorn refreshes the HTTP layer but leaves the background scheduler running with the old configuration in memory.


Common tasks

Add an M3U or Xtream Codes source

  1. Open Dispatcharr at https://your-server/username/dispatcharr/
  2. Go to Playlists → Add Playlist
  3. Enter the M3U URL or Xtream Codes credentials
  4. Save — Dispatcharr fetches the playlist and lists the channels
  5. (Optional) Edit channel names, numbers, or group assignments under Channels

Add EPG data

  1. Go to EPG → Add EPG Source
  2. Enter the XMLTV URL or Xtream EPG endpoint
  3. Save — Dispatcharr fetches the EPG and matches it against your channel list
  4. Use Manual Match for any channels that did not match automatically

Connect Plex, Emby, or Jellyfin

Dispatcharr emulates an HDHomeRun tuner so your media server’s Live TV setup can use it without a physical capture card. The tuner is published at the /hdhr path under your Dispatcharr URL:

https://your-server/username/dispatcharr/hdhr

When Dispatcharr is published on a dedicated subdomain, the tuner URL is:

https://dispatcharr.example.com/hdhr

QuickBox’s nginx template forwards the Host header to Dispatcharr, so the HDHomeRun discovery response advertises stream URLs on your public domain rather than an internal address — the media server can reach those URLs directly.

Plex Live TV (manual tuner)

Plex does not always auto-discover a software tuner across the internet, so add it by URL:

  1. In Plex, open Settings → Live TV & DVR → Set up Plex DVR
  2. When Plex cannot find a tuner automatically, click Don’t see your HDHomeRun device? / Enter its network address manually
  3. Enter the Dispatcharr HDHR URL: https://your-server/username/dispatcharr/hdhr (or your subdomain https://dispatcharr.example.com/hdhr)
  4. Plex reads the channel lineup from Dispatcharr — map the EPG and select the channels to expose
  5. Finish the DVR setup and start watching Live TV

Emby and Jellyfin

  1. Open Live TV → Tuner Devices → Add in the media server’s dashboard
  2. Choose HDHomeRun as the tuner type
  3. Enter the Dispatcharr HDHR URL: https://your-server/username/dispatcharr/hdhr
  4. Add an EPG/Guide Data source and map it to the channels
Plex requires AC3 audio on the Dispatcharr output

Plex’s bundled FFmpeg cannot copy AAC audio into its Live TV segmenter. When the Dispatcharr stream delivers AAC audio, Plex fails to tune with “Could not tune channel. Please check your tuner or antenna.” even though Emby and Jellyfin play the same channel fine. The fix is a Dispatcharr output profile that re-encodes audio to AC3 while copying the video stream, applied to the channels Plex tunes. QuickBox seeds this profile (named Plex HDHR (transcode)) automatically on install, reinstall, and update — so an existing install picks it up on its next qb update dispatcharr. The seeding is idempotent and never overwrites an output profile you have already bound. See Plex says “Could not tune channel” in Troubleshooting.

Keep Plex’s channel map in sync (automatic)

Plex caches a map that pairs each Live TV guide channel to a tuner channel number. When you renumber channels in Dispatcharr, that cached map goes stale and Plex starts tuning the wrong channel. QuickBox keeps the map corrected for you:

  • A per-user self-heal runs on a schedule (every 8 hours, with a randomized delay so a fleet of servers never hits Plex in lockstep) and re-syncs Plex’s channel map to your current Dispatcharr lineup.
  • It also runs once automatically at install and update time, and is enabled the moment Dispatcharr is installed.
  • It is idempotent — when the map is already in sync it makes no changes, so there is no harm in it running on a steady cadence.
  • It is a graceful no-op on servers without Plex Live TV (no Plex, no DVR, or no channels) — it never error-spams.

You can also force a correction immediately rather than waiting for the next scheduled run — see Plex tunes the wrong channel after a lineup change in Troubleshooting for the manual qb manage dispatcharr channelmap command.

No setup required

The self-heal is wired up automatically — there is nothing to enable. If you remove Dispatcharr, the self-heal timer is torn down with it.

Update Dispatcharr

qb update dispatcharr -u username

The update process stops the four application services, pulls the latest commits from the configured branch, rebuilds the Python venv and React frontend, re-runs Django migrations, and restarts the services. The per-user PostgreSQL database and Redis data are not touched.

Remove Dispatcharr

qb remove dispatcharr -u username

This stops and disables all six per-user services, removes the install directory, configuration, data, PostgreSQL cluster, and Redis directory, and removes the nginx subpath configuration. Once removed, Dispatcharr cannot be restored from the install tree — restore from a QuickBox backup if you need historical data.


Plugins

Dispatcharr supports drop-in Python plugins for custom stream handling, channel transformations, and provider integrations. QuickBox points the plugin loader at a per-user directory so each user’s plugin set is isolated from every other user’s.

Plugin directory

/home/username/.local/share/dispatcharr/plugins/

The path is exported to Dispatcharr through the DISPATCHARR_PLUGINS_DIR variable in ~/.config/dispatcharr/.env. Upstream Dispatcharr’s plugin loader (in apps/plugins/loader.py) reads this variable at app-ready time — if it is unset, the loader falls back to the Docker-image default /data, which does not exist on a QuickBox install and crashes the Daphne service with PermissionError: [Errno 13] Permission denied: '/data'. QuickBox sets the variable for you; do not remove it.

Installing a plugin

  1. Save your plugin .py file (or its package directory) under ~/.local/share/dispatcharr/plugins/
  2. Make sure the file is owned by your QuickBox user
  3. Restart the application services so the loader picks it up
# As your QuickBox user — copy the plugin into place cp /path/to/my_plugin.py ~/.local/share/dispatcharr/plugins/ # Restart the four application services sudo systemctl restart dispatcharr-gunicorn@username \ dispatcharr-daphne@username \ dispatcharr-celery-worker@username \ dispatcharr-celery-beat@username

The per-user PostgreSQL and Redis services do not need to be restarted — they hold no plugin state.

Plugin authoring

See the upstream Dispatcharr repository for the plugin API and example plugins. QuickBox does not modify the plugin contract — anything that works on a vanilla Dispatcharr install will load on a QuickBox install as long as it sits in the per-user plugins directory.


Troubleshooting

Dispatcharr will not start

Symptoms

  • systemctl status dispatcharr-gunicorn@username shows failed
  • Web UI returns 502 Bad Gateway from nginx
  • Recent install did not finish cleanly

What to check

  • Check journal logs: journalctl -u dispatcharr-gunicorn@username -n 100
  • Verify the per-user PostgreSQL is up: systemctl status postgresql@username
  • Verify the per-user Redis is up: systemctl status redis@username
  • Confirm the .env file exists at /home/username/.config/dispatcharr/.env
  • Run qb reinstall dispatcharr -u username to rebuild the install

Login returns 500 — PostgreSQL shared memory error

The Daphne or Gunicorn log shows:

psycopg.OperationalError: FATAL: could not open shared memory segment "/PostgreSQL.<id>"

This means the per-user PostgreSQL cluster lost its shared-memory segment because systemd-logind swept it. By default, logind’s RemoveIPC=yes policy wipes a user’s SysV shared-memory segments the moment no live session exists for that user — and dashboard-driven installs typically run with no interactive session for the install user. PostgreSQL’s shared_buffers allocation lives in those segments; once swept, every connection attempt fails with the error above and Django returns 500.

The fix is to enable systemd-logind linger for the user, which tells logind to leave the user’s IPC objects alone:

# Enable linger (persists across reboots, scoped to this user only) sudo loginctl enable-linger username # Confirm loginctl show-user username | grep Linger # expected: Linger=yes # Restart the per-user PostgreSQL and the application services sudo systemctl restart postgresql@username sudo systemctl restart dispatcharr-gunicorn@username \ dispatcharr-daphne@username \ dispatcharr-celery-worker@username \ dispatcharr-celery-beat@username

QuickBox enables linger automatically during a fresh qb install dispatcharr and qb reinstall dispatcharr. If you see the error on an existing install made before this safeguard, run the commands above once — the change is persistent and idempotent.

Login returns 500 — PermissionError on /data

The Daphne log shows:

PermissionError: [Errno 13] Permission denied: '/data'

This means Dispatcharr’s plugin loader is falling back to its Docker-image default plugin root (/data), which does not exist on a QuickBox install. The fix is to make sure the DISPATCHARR_PLUGINS_DIR variable is set in your .env and points at the per-user plugins directory, then restart the application services so they re-read the environment file:

# Confirm the variable is set grep DISPATCHARR_PLUGINS_DIR /home/username/.config/dispatcharr/.env # expected: DISPATCHARR_PLUGINS_DIR=/home/username/.local/share/dispatcharr/plugins # Confirm the directory exists and is owned by your user ls -la /home/username/.local/share/dispatcharr/plugins # Restart the four application services sudo systemctl restart dispatcharr-gunicorn@username \ dispatcharr-daphne@username \ dispatcharr-celery-worker@username \ dispatcharr-celery-beat@username

If the variable is missing from .env, qb reinstall dispatcharr -u username regenerates the file with the correct value. App-scoped VPN routing has no effect on this error — the same fix applies whether routing is on or off.

EPG data is missing or stale

# Check whether the Celery worker is running systemctl status dispatcharr-celery-worker@username # Check whether the Celery beat scheduler is running systemctl status dispatcharr-celery-beat@username # Tail the Celery logs while you trigger an EPG refresh from the UI journalctl -u dispatcharr-celery-worker@username -f

If both Celery services are running and logs show fetch attempts, verify the XMLTV URL is reachable from the server (curl -I "your-epg-url") and check Dispatcharr’s EPG Sources page for error messages.

Channels load but streams will not play

# Confirm ffmpeg is installed and reachable from Dispatcharr's venv ls -la /opt/username/dispatcharr/env/bin/ffmpeg # Test the upstream stream URL directly with ffmpeg ffmpeg -i "your-stream-url" -t 5 -f null - # Tail Gunicorn logs while attempting playback journalctl -u dispatcharr-gunicorn@username -f | grep -i "stream\|ffmpeg"

Plex says “EPG/XMLTV invalid or missing file”

Plex shows “EPG/XMLTV invalid or missing file” (or rejects a guide URL outright) when you try to give Plex an XMLTV/EPG file or URL directly. This is the most common Dispatcharr-to-Plex setup mistake, and the error is working as designed: Plex never reads your guide file. The XMLTV/Xtream EPG source belongs inside Dispatcharr, not in Plex.

The fix is to set the guide up in the right place:

  1. Open Dispatcharr at https://your-server/username/dispatcharr/
  2. Go to EPG → Add EPG Source and add your XMLTV URL or Xtream EPG endpoint there — let Dispatcharr fetch and match it against your channels
  3. In Plex, remove any guide file or guide URL you tried to add, and instead add only the Dispatcharr HDHomeRun tuner at https://your-server/username/dispatcharr/hdhr (or your subdomain https://dispatcharr.example.com/hdhr)
  4. Plex reads the channels and the guide from that one tuner — there is no separate guide file to configure in Plex

See How to: connect Dispatcharr to Plex for the full connection order. If your guide still looks wrong after Plex is tuning Dispatcharr channels, that is a different issue — see Plex’s guide shows the wrong program or channel.

Plex says “Could not tune channel”

Plex shows “Could not tune channel. Please check your tuner or antenna.” when you try to watch a Dispatcharr channel, while the same channel plays fine in Emby or Jellyfin. The cause is the stream’s audio codec: Plex’s bundled FFmpeg cannot copy AAC audio into its Live TV segmenter, so the tune fails before playback starts. Emby and Jellyfin do not have this limitation, which is why they play the same channel without complaint.

The fix is to make Dispatcharr deliver AC3 audio to Plex. Dispatcharr does this with an output profile that re-encodes audio to AC3 and copies the video stream, applied to the channels Plex tunes:

  1. Open Dispatcharr at https://your-server/username/dispatcharr/
  2. Go to Settings → Stream Profiles / Output Profiles
  3. Create (or edit) an output profile that:
    • copies the video stream (no video re-encode — keeps CPU low)
    • re-encodes audio to AC3 at 48 kHz stereo (for example FFmpeg -c:v copy -c:a ac3 -ar 48000 -ac 2)
  4. Assign that output profile to the channels Plex tunes (or set it as the default output)
  5. In Plex, retry the channel — it should tune and play
QuickBox seeds this for you

QuickBox seeds an output profile named Plex HDHR (transcode) — video copied, audio AC3 48 kHz stereo — and binds it as the HDHR default so Plex tuning works out of the box. It runs on install, reinstall, and update, so an existing install picks it up on its next qb update dispatcharr -u username with no reinstall needed. The seeding is idempotent and never overwrites an output profile you have already bound, so a custom profile is left untouched. Emby and Jellyfin keep working regardless of which audio codec the profile uses.

Plex’s guide shows the wrong program or channel

A channel tunes and plays in Plex, but Plex’s own program guide shows the wrong show — for example the row labelled “Comedy Central” displays the schedule for “US: AXS TV HD”, or a channel shows no guide data at all. The channel number and name can be perfectly clean and the guide still wrong, because the guide content is matched on a separate field, not the channel number.

The QuickBox dashboard already shows the correct guide

The QuickBox dashboard (WSDashboard) reads the EPG straight from Dispatcharr, so it shows the correct channel and program for every channel — regardless of any Gracenote mapping. This is the recommended way to view accurate live-TV info. Fixing the guide inside Plex’s own app is optional, and it only works for channels that have a real over-the-air broadcast equivalent. If you only ever watch live TV through the dashboard, you can skip this section entirely.

The cause is how Plex builds its native Live TV guide. Plex does not read the EPG you configured in Dispatcharr for its app guide — it matches each HDHomeRun channel to its own Gracenote cloud guide using a station id (tvc_guide_stationid). That station id is a different field from the channel number: a channel can be numbered and named correctly yet still carry the wrong station id (or none), which is why Plex shows the wrong schedule even when the dashboard is right. When a channel has no Gracenote station id, Plex either guesses and mismaps it, or leaves the guide blank.

Important: Dispatcharr’s EPG matching does not produce Gracenote station ids. Dispatcharr’s Auto-Match matches each channel to your provider’s XMLTV EPG (the tvg-id, e.g. 4UV.us). That is what makes Dispatcharr and the QuickBox dashboard show the correct program — but it has nothing to do with Gracenote. On a typical install the only EPG source is the provider XMLTV; there is no Gracenote data in Dispatcharr at all. Gracenote station ids therefore have to be sourced externally and assigned to your channels by hand.

There is also no Plex setting to fix the mapping — Plex will not let you reassign a station for a software tuner. You fix it at the source by putting a correct Gracenote tvc_guide_stationid on each channel in Dispatcharr, so the HDHomeRun lineup advertises it to Plex.

Workflow (only for channels with a real broadcast equivalent):

  1. Open Dispatcharr at https://your-server/username/dispatcharr/
  2. Find the Gracenote station id for the real broadcast channel. The community global-channel-search tool queries a Gracenote/zap2it dataset and returns the station id for a given call sign or channel name. You can also look it up manually against a public Gracenote/zap2it listing.
  3. Assign that station id to the matching channel in Dispatcharr (the tvc_guide_stationid / Gracenote guide-id field on the channel), and confirm the HDHomeRun output is advertising it in the lineup it serves to Plex.
  4. In Plex, re-scan the tuner so it picks up the new station ids — open Settings → Live TV & DVR, select the Dispatcharr DVR, and refresh the guide (or remove and re-add the tuner if the guide does not update). Plex now matches each channel to its correct Gracenote station.
Pure-IPTV channels can never map in Plex's native guide

Only channels with a real over-the-air broadcast equivalent (AXS TV, Comedy Central, and the like) exist in Plex’s Gracenote catalog and can be assigned a station id. Pure-IPTV, regional, foreign-language, or niche channels have no Gracenote station, so Plex’s native app guide can never label them correctly no matter what you do. For those channels — and indeed all channels — view live TV through the QuickBox dashboard, which reads the EPG directly from Dispatcharr and always shows the correct program.

Plex tunes the wrong channel after a lineup change

You select one Live TV channel in Plex and a different channel plays — for example you pick Animal Planet and Hallmark comes on instead. This usually starts right after your Dispatcharr channel lineup is renumbered (you reordered channels, added or removed channels, or re-ran a playlist import that shifted channel numbers).

QuickBox now corrects this automatically

You normally do not have to do anything. QuickBox runs a scheduled self-heal that re-syncs Plex’s channel map to your current Dispatcharr lineup several times a day, so a stale map corrects itself without action. The manual command below is for when you want to force the correction immediately instead of waiting for the next scheduled run.

The cause is a stale channel map inside Plex. When you first set up the Dispatcharr tuner, Plex pairs each guide channel to a tuner channel by name, then caches the channel number. When Dispatcharr later renumbers a channel, Plex keeps the old number — so it tunes whatever channel now sits at that number. The Dispatcharr lineup itself stays correct; only Plex’s cached map drifts. This is different from the guide-mismatch issue above: there the channel plays correctly but the program guide is wrong; here the wrong channel plays entirely.

Force a correction on demand. QuickBox ships a corrector you can run as the server administrator. It runs in dry-run mode by default so you can preview exactly what would change before anything is written:

# Preview the changes (dry-run — writes nothing) qb manage dispatcharr channelmap --user username # Apply the corrected map (backs up the current map first, then reloads the guide) qb manage dispatcharr channelmap --user username --apply

The corrector:

  1. Reads your current Dispatcharr lineup as the source of truth
  2. Compares it to Plex’s cached channel map and prints a before/after summary of every channel that would move
  3. On --apply, backs up the current map first (to /home/username/plex-dvr-backup-<timestamp>.xml), writes the corrected map, then reloads the Plex guide
  4. Is idempotent — if the map is already in sync it makes no changes and exits cleanly
Run as the server administrator

qb manage dispatcharr channelmap is a server-administrator operation — it must be run with root privileges (for example by the super admin who owns the box). The target user (passed with —user) must have both Dispatcharr and Plex installed. Always run the dry-run first and review the summary before adding —apply.

If the dry-run reports no changes but Plex still tunes the wrong channel, the problem is upstream of the map — confirm the channel actually plays the right stream in the QuickBox dashboard or in Emby/Jellyfin, then re-check the Dispatcharr channel number for that channel.

WebSocket connections fail (live UI updates do not work)

WebSocket traffic is handled by Daphne under the /ws/ location. Confirm:

systemctl status dispatcharr-daphne@username journalctl -u dispatcharr-daphne@username -n 50

Some reverse proxies in front of QuickBox (Cloudflare, custom front-end nginx) require explicit WebSocket upgrade configuration. If you sit behind one, make sure WebSocket traffic on /username/dispatcharr/ws/ is allowed to pass through.

Reset Dispatcharr while keeping your QuickBox account

Reinstall preserves the per-user PostgreSQL data:

qb reinstall dispatcharr -u username

If you want a clean slate including database, do a full remove and reinstall:

qb remove dispatcharr -u username qb install dispatcharr -u username

Best practices

Do

  • Rotate the auto-generated admin password from inside Dispatcharr after your first successful login
  • Use stable channel sources — flaky M3U providers cause buffering and EPG mismatch noise
  • Match EPG channel IDs to your M3U channels carefully so guide data lines up
  • Configure transcoding profiles per channel — full-bitrate streams are not always needed for mobile clients
  • Store DVR recordings on disks with capacity for your retention window
  • Keep Dispatcharr updated with qb update dispatcharr -u username for upstream fixes
  • Use VPN routing if your IPTV provider's terms require it or you want to mask upstream egress
  • Back up your Dispatcharr config and database from the QuickBox dashboard before major changes

Don't

  • Don't loosen the .admin_credentials or .env file permissions — both files hold secrets
  • Don't expose Dispatcharr's internal Gunicorn or Daphne ports to the internet — always go through nginx
  • Don't share IPTV provider credentials publicly or commit them to a repository
  • Don't try to share one Dispatcharr instance between QuickBox users — each user owns their own stack
  • Don't edit .env while Dispatcharr is running — restart Gunicorn after any change
  • Don't manually change the per-user PostgreSQL port or Redis port — QuickBox manages them through systemd units
  • Don't remove DISPATCHARR_PLUGINS_DIR from .env — the plugin loader falls back to a Docker-only path and crashes
  • Don't use Dispatcharr to stream content you do not have a license for

FAQ

QuickBox auto-generates the admin password at install time. The preferred way to retrieve it is the QuickBox dashboard — open the App Dashboard, expand the Dispatcharr row, and the API & Secrets section shows the username and a click-to-reveal password. If you have not opened the dashboard yet, you can also read the credentials directly from the server at ~/.config/dispatcharr/.admin_credentials over SSH. The file uses a simple username=... / password=... format and is mode 0640 owned username:qbusers.
Drop the plugin .py file (or its package directory) into ~/.local/share/dispatcharr/plugins/ as your QuickBox user, then restart the four application services (dispatcharr-gunicorn, dispatcharr-daphne, dispatcharr-celery-worker, dispatcharr-celery-beat) so the loader picks the plugin up. The directory is per-user — your plugins do not leak to other QuickBox users on the same server.
Two known root causes both surface as 500 after a successful login POST. The first is a psycopg.OperationalError about shared memory, fixed by running sudo loginctl enable-linger username so systemd-logind stops sweeping PostgreSQL's shared-memory segments. The second is a PermissionError: [Errno 13] Permission denied: '/data', fixed by confirming DISPATCHARR_PLUGINS_DIR is set in ~/.config/dispatcharr/.env. Both fixes require restarting the four application services. See Troubleshooting for the exact commands.
Yes. Every user who installs Dispatcharr gets an isolated stack — its own PostgreSQL cluster, Redis broker, application services, admin account, channel lineup, EPG sources, and DVR storage. Users do not share data.
The first install on the box primes host-level dependencies — apt-installs PostgreSQL, Redis, and FFmpeg, and disables any system-wide postgresql.service and redis-server.service so each user can run their own isolated cluster. Those operations need an admin (a user with user_level >= 9). Once any admin has completed the first install, every QuickBox user can install their own per-user instance — subsequent installs skip the system-level setup entirely and only provision the per-user stack.
No. The dashboard install dialog always targets the currently signed-in user — there is no user picker in the dialog. To install Dispatcharr for a different user, use the CLI with an explicit -u <other_user>.
Yes, but not for the same QuickBox user. Each user runs one Dispatcharr instance. Two different users on the same server can run different branches — pass --beta to install the development branch for one user, omit it for the other.
QuickBox assigns a free external HTTP port near the upstream default of 9191 at install time and stores it in the QuickBox database. The Dispatcharr row in the dashboard's App Dashboard shows it — this row port is the main Dispatcharr web application (Gunicorn) and is the one you use when you need a direct URL (for example a same-box Plex tuner). Expanding the row also shows a Daemon port: that is Dispatcharr's WebSocket service (Daphne) for live UI updates, not the tuner — do not use it for Plex. You normally do not need to access either port directly — nginx proxies /username/dispatcharr/ for you.
Dispatcharr's internal services bind to 127.0.0.1 (loopback) only, so a tuner URL built from the server's LAN IP and a raw port — for example http://192.168.x.x:<port>/hdhr — can never reach Dispatcharr, even on your own home network. Use one of the two URLs that work instead: if Plex runs on the same QuickBox server as Dispatcharr, point it at http://127.0.0.1:<PORT>/hdhr where <PORT> is the main port on the Dispatcharr row in the App Dashboard (not the Daemon port in the expansion panel); if Plex runs on any other device, use the nginx URL https://your-server/username/dispatcharr/hdhr (subpath) or https://dispatcharr.example.com/hdhr (subdomain). See Which URL do I give Plex? for the full breakdown.
No. qb update dispatcharr -u username pulls the latest source, rebuilds the Python venv and frontend, runs Django migrations, and restarts services. The per-user PostgreSQL database and the data directory at /home/username/.local/share/dispatcharr/ are left untouched.
Yes. Open System → VPN Control in the dashboard, scroll to the App-Scoped Routing card, and select Dispatcharr. QuickBox moves all four Dispatcharr application services (Gunicorn, Daphne, Celery worker, Celery beat) into one shared VPN network namespace (qb_dispatcharr). PostgreSQL and Redis stay on the host because they bind localhost only.
Yes — three paths are supported. The fastest is to pass -d <domain> to qb install dispatcharr when you first install (Path A) — the install issues the SSL cert and writes the subdomain vhost in one call. If Dispatcharr is already installed, run qb install lecert --dispatcharr -d <domain> -u <username> to retrofit a subdomain (Path B), or open System → SSL Control in the dashboard, pick Dispatcharr as the target, enter the domain and username, and submit (Path C). All three paths produce the same end state. See the Custom subdomain with SSL section above for the full flow.
Yes. Dispatcharr emulates an HDHomeRun tuner published at the /hdhr path under your Dispatcharr URL (for example https://your-server/username/dispatcharr/hdhr). Emby and Jellyfin add it under Live TV → Tuner Devices → Add → HDHomeRun. Plex may not auto-discover it, so in Set up Plex DVR click the option to enter the tuner network address manually and paste the /hdhr URL. One extra step is required for Plex — the stream must deliver AC3 audio (see the AC3 question below).
You tried to give Plex a guide file or guide URL directly. Plex does not read your XMLTV/EPG file at all — that is by design. The guide source belongs inside Dispatcharr: add it under EPG → Add EPG Source in Dispatcharr's web UI, let Dispatcharr match it to your channels, and then point Plex at only Dispatcharr's HDHomeRun tuner (https://your-server/username/dispatcharr/hdhr). Plex reads the channels and the guide from that one tuner — there is no separate guide file to configure in Plex. See How to: connect Dispatcharr to Plex for the full connection order.
Plex's bundled FFmpeg cannot copy AAC audio into its Live TV segmenter, so a Dispatcharr channel with AAC audio fails to tune with "Could not tune channel. Please check your tuner or antenna." Emby and Jellyfin do not have this limitation. The fix is a Dispatcharr output profile that re-encodes audio to AC3 and copies the video stream, assigned to the channels Plex tunes. QuickBox seeds this AC3 output profile automatically on new installs; on older installs create it under Settings → Stream Profiles / Output Profiles (or run qb reinstall dispatcharr -u username). See Troubleshooting for the exact steps.
First, the QuickBox dashboard already shows the correct program for every channel — it reads the EPG straight from Dispatcharr, so it is the recommended way to view live TV. Fixing the guide inside Plex's own app is optional. Plex builds its native guide from its own Gracenote cloud guide, matching each HDHomeRun channel by a station id (tvc_guide_stationid) — a field separate from the channel number, so a channel can be numbered correctly and still show the wrong schedule. Note that Dispatcharr's Auto-Match matches channels to your provider's XMLTV EPG (the tvg-id), not to Gracenote — it does not produce station ids. Gracenote station ids must be sourced externally (the community global-channel-search tool or a manual lookup) and assigned to each channel in Dispatcharr, then the tuner re-scanned in Plex. Only channels with a real broadcast equivalent have a Gracenote station; pure-IPTV channels never will, so Plex's native guide can never label those — view them through the dashboard instead. See Troubleshooting for the full workflow.
Plex caches a map that pairs each guide channel to a tuner channel number, set by name when you first add the tuner. When you renumber channels in Dispatcharr, Plex keeps the old number and tunes whatever channel now sits there — so picking one channel plays another. QuickBox corrects this automatically: a per-user self-heal re-syncs Plex's channel map to your current Dispatcharr lineup on a schedule (every 8 hours) and also at install/update time, so a stale map fixes itself. To force the correction immediately, a server administrator can run qb manage dispatcharr channelmap --user username for a dry-run preview, then add --apply to write the corrected map — it backs up the current map first and reloads the guide. See Troubleshooting for details. This is a different problem from a wrong program guide — see the Gracenote question above for that.
The tuner is published at the /hdhr path under your Dispatcharr URL: https://your-server/username/dispatcharr/hdhr on the per-user subpath, or https://dispatcharr.example.com/hdhr when published on a dedicated subdomain. QuickBox's nginx forwards the Host header so the HDHomeRun discovery response advertises stream URLs on your public domain, which lets the media server reach them directly.
Per-service logs are in the systemd journal — for example journalctl -u dispatcharr-gunicorn@username -f. Application-level logs that Dispatcharr writes itself live under /home/username/.local/share/dispatcharr/logs/.

Media Servers

Alternative IPTV Proxy

Networking and Privacy


Resources

Join the Community

Media server operators sharing configs, getting support, and shaping the future of QuickBox Pro.

Dedicated Support
Feature Previews
Community Configs
Active Discussions
Join Discord Server
Last updated on