Quikcast Help

Continuous fallback mounts

Fallback is internal listener routing at admission. A player keeps its requested URL and receives the first usable continuous source generation in its configured chain. There is no redirect or wait for a source.

Configure a chain

[limits] max_listeners = 1000 listeners_per_mount = 1000 [[mounts]] path = "/main" fallback = "/backup" secret_file = "secrets/main-source" [[mounts]] path = "/backup" fallback = "/last" secret_file = "secrets/backup-source" [[mounts]] path = "/last" secret_file = "secrets/last-source"

fallback is optional and defaults to no fallback. Its value must exactly match another configured canonical continuous mount path. All existing path, credential and resource validation still applies. Unknown targets, self-reference, cycles, duplicate paths, noncanonical targets and chains longer than eight mounts including the requested mount reject startup before binding. HLS paths cannot be targets. Configuration changes require restart.

The route is compiled once into an ordered list of mount references. On GET, Quikcast attempts each mount in order. A mount is usable only with a streaming, uncancelled generation and the initialization required by its media parser. A connecting source or incomplete Ogg/FLAC initialization permits fallback. If all candidates are unavailable, the existing 404 Mount unavailable response contains no topology information. A full usable mount returns the normal capacity error; its limit does not cause routing to a later mount. Authentication errors, drain and other failures also do not cause fallback.

HEAD follows the same availability order and describes the serving source. It creates no listener lease, consumes no listener permit and records no fallback admission. It is a momentary metadata observation, not a guarantee that a subsequent GET will choose the same source.

Ownership and recovery

A request for /main served by /backup records requested_mount: "/main" and serving_mount: "/backup". The backup owns the listener generation, cursor, ring references, initialization, local listener permit, listener registry, active count and body-byte accounting. The requested mount supplies routing intent and consumes no listener permit. Global listener and connection caps remain authoritative; one listener consumes one global listener permit.

Existing fallback listeners stay on their selected generation when the primary returns. New requests prefer the restored primary. A source may claim the primary normally while fallback listeners exist. A second source on an occupied primary is still rejected. There is no source replacement, suspension, priority, emergency policy or source stack.

When the serving source disconnects, existing listeners close through the ordinary generation lifecycle. They do not migrate to the next fallback or a reconnected serving source. A player reconnect resolves the chain afresh. During drain, existing fallback streams continue and new admissions are rejected; normal shutdown closes them.

Resolution observes mounts sequentially, not through an atomic graph snapshot. If a primary becomes usable after the request already selected a backup, that request can commit on the backup. Each candidate is attempted at most once. A candidate that disconnects or reconnects before commit is skipped for that request, even if its replacement is now usable; later requests can select the replacement. These rules bound work while preserving exact generation ownership.

Format, headers and metadata

Mount names/extensions do not define formats. Fallback can cross continuous codecs. An MP3-named URL served by Ogg Opus advertises the serving source's actual Ogg MIME and sends its cached initialization and pages. Quikcast does not convert audio. Players must accept the actual response format; clients hard-coded to an extension or codec may need configuration or a reconnect-capable player. Automated tests verify MP3-to-MP3 and MP3-request-to-Ogg response behavior, not universal player compatibility.

Station headers, track state and initialization come exclusively from the selected generation. MP3/AAC ICY blocks follow that serving generation when requested by the client. Ogg/native FLAC do not gain ICY byte insertion through fallback. No primary station/track values are merged. Source-authenticated metadata updates and native source controls still address the actual source's mount; updates to an unavailable primary do not change backup metadata.

Relay mounts use these same generation semantics. /main -> /relay -> /backup requires no relay-specific routing: connected relay generations can serve requests, and unavailable relays permit the next candidate. Dedicated relay source ownership and operator stop/reconnect behavior remain unchanged. HLS stays independent.

Inspect use

Authenticated mount snapshots include fallback, either its configured target or null. Listener snapshots add requested_mount and serving_mount; the existing mount field retains its serving-mount meaning. /api/listeners?mount=... filters the serving registry. Inspect the backup's listeners to find requests originally made to its primary. Per-mount bytes and active listeners are also attributed only to the serving mount.

fallback_listener_admissions_total is a fixed unlabeled counter in Prometheus and /api/stats, incremented once after successful fallback commit. Failed attempts, HEAD and direct-primary admissions do not increment it. One structured INFO event records requested mount, serving mount and generation per fallback admission; audio chunks add no routing logs. Listener close logs preserve both identities.

See the completion review for the admission boundary and tests. Live listener migration/failback, source takeover/priorities, health-based source failover and HLS fallback are separate future work.

08 October 2026