Skip to content

InfiniDysk (Core Service)#

InfiniDysk is a combined backend + frontend WebDAV service for Usenet workflows. In DUMB it runs as a single service that exposes a Web UI, a WebDAV endpoint for browsing/serving content, and a backend API used for automation.

Workflow diagram#

%%{ init: { "flowchart": { "curve": "basis" } } }%%
flowchart TD
    A([Request Sources:<br/>Seerr, Trakt,<br/>Plex Watchlist,<br/>NeutArr])
    B[Arr Services:<br/>Sonarr, Radarr,<br/>Lidarr,<br/>Whisparr]
    C[[Prowlarr / Indexers]]
    D[InfiniDysk]
    E@{shape: cloud, label: "Usenet Providers"}
    F[[Rclone]]
    G[(WebDAV Mount Root:<br/>/mnt/debrid/<br/>infinidysk)]
    H[(QBit Download Symlinks:<br/>/mnt/debrid/infinidysk/<br/>completed-symlinks)]
    I[Arr Rename + Link Step:<br/>Hard Link / Symlink]
    J[(Final Symlink Root:<br/>/mnt/debrid/<br/>infinidysk-symlinks)]
    K([Media Servers:<br/>Plex, Jellyfin,<br/>Emby])

    E === D
    D === F
    linkStyle 0 stroke:transparent,stroke-width:0;
    linkStyle 1 stroke:transparent,stroke-width:0;

    A ==> B
    C <==> B
    B <==> D
    D e1@==> E
    F e2@==> D
    F e3@==> G
    D ==> H
    H ==> G
    H ==> B
    B ==> I
    I ==> J
    J e4@==> G
    K e5@<==> J


    classDef animate stroke-dasharray: 9,5,stroke-dashoffset: 900,animation: dash 25s linear infinite;
    class e1,e2,e3,e4,e5 animate

Service Relationships#

Classification Role
Core Service NZB WebDAV gateway
Depends On rclone
Optional Sonarr, Radarr, Lidarr, Whisparr, Prowlarr, NeutArr
Exposes UI Yes (Web UI + WebDAV)

What InfiniDysk provides#

Endpoint Purpose Default
Web UI + WebDAV Primary UI and WebDAV endpoint http://<host>:3000/
Backend API Internal API for DUMB automation http://127.0.0.1:8080/

InfiniDysk also exposes a Usenet download client path in Arr by emulating a Sabnzbd-compatible API. DUMB registers this client automatically when core_service: infinidysk (or core_service includes infinidysk) is set on Arr instances.

WebDAV endpoint

rclone and Arr download clients point at the WebDAV endpoint on the frontend port.


Configuration in dumb_config.json#

DUMB defaults to InfiniDysk

DUMB installs and updates the renamed project from infinidysk/infinidysk by default. The legacy nzbdav DUMB service key and NZBDAV_* environment variables remain compatibility aliases. Existing configs containing either former DUMB repository default, nzbdav-dev/nzbdav or nzbdav/nzbdav, follow the maintained repository automatically; intentional custom forks remain unchanged. User-visible identity changes remain opt-in.

Support the maintainer

If InfiniDysk is useful to your stack, you can support the maintainer through Buy Me a Coffee. DUMB also exposes this link through the frontend's InfiniDysk service page and Settings → About.

"infinidysk": {
    "enabled": false,
    "process_name": "InfiniDysk",
    "repo_owner": "infinidysk",
    "repo_name": "infinidysk",
    "release_version_enabled": false,
    "release_version": "latest",
    "commit_sha": "",
    "branch_enabled": false,
    "branch": "main",
    "suppress_logging": false,
    "log_level": "INFO",
    "frontend_port": 3000,
    "backend_port": 8080,
    "auto_update": false,
    "auto_update_interval": 24,
    "auto_update_start_time": "04:00",
    "symlink_backup_enabled": false,
    "symlink_backup_interval": 168,
    "symlink_backup_start_time": "04:00",
    "symlink_backup_path": "/config/symlink-repair/snapshots/infinidysk-{timestamp}.json",
    "symlink_backup_include_broken": true,
    "symlink_backup_retention_count": 1,
    "symlink_backup_roots": [
        "/mnt/debrid/infinidysk-symlinks"
    ],
    "clear_on_update": false,
    "exclude_dirs": [],
    "platforms": [
        "pnpm",
        "dotnet"
    ],
    "command": [],
    "config_dir": "/infinidysk",
    "log_file": "/log/infinidysk.log",
    "webdav_password": "",
    "env": {}
},

Key Configuration Fields#

  • enabled: Toggle to run InfiniDysk via DUMB.
  • frontend_port: Port for the Web UI and WebDAV endpoint.
  • backend_port: Port for the backend API.
  • commit_sha: Optional full 40-character GitHub SHA. When set, DUMB builds that exact InfiniDysk revision instead of selecting a release or branch.
  • webdav_password: Default WebDAV password (overridden by WEBDAV_PASSWORD).
  • config_dir: Path where InfiniDysk data is stored.
  • log_file: Path for the consolidated InfiniDysk log.
  • env: Optional environment variables (see below).

WebDAV credentials

If webdav_password is blank, DUMB generates one at startup and stores it in the config. Change the password before exposing InfiniDysk outside your trusted network.

Tracking a moving InfiniDysk release tag#

InfiniDysk tags do not need a matching GitHub Release. To track a tag such as dev, enable the release selector and use the tag name:

"infinidysk": {
    "release_version_enabled": true,
    "release_version": "dev",
    "commit_sha": "",
    "branch_enabled": false,
    "auto_update": true
}

DUMB treats any digit-free InfiniDysk tag, such as dev, lts, or edge, as a moving release channel. With auto_update: true, DUMB checks it at the normal configured interval and installs it when the underlying commit changes. Manual Check for updates and Install update remain available.

With auto_update: false, startup validates and keeps an already installed runtime even when the moving tag now points at another commit. DUMB does not turn a container restart into an implicit channel update. Use the Updates panel to install the newly resolved commit deliberately. If the installed backend or frontend runtime is incomplete, startup still attempts the configured channel so a broken or missing installation can recover.

The installed marker is recorded as dev-<short-sha>. The source archive is downloaded by the resolved full SHA, so the installed source and recorded marker remain consistent even if the tag moves during the update.

Prebuilt archives and automatic source fallback#

For InfiniDysk release selectors, DUMB first looks for the official architecture-specific linux-x64 or linux-arm64 release archive. It requires GitHub's published SHA-256 digest, resolves the selected tag to its full commit, requires the release asset's target commit to still match that tag, validates the complete backend and frontend runtime, and activates them as one rollback-safe unit. DUMB selects the exact channel asset deterministically and accepts only InfiniDysk or legacy NzbDAV archive roots for the selected CPU architecture. This handles renamed rolling assets such as rc, whose downloaded archive can keep the concrete RC version in its internal root directory.

If a selected tag has no GitHub Release object, has no compatible archive, or has release assets that lag behind a moved channel tag, DUMB automatically downloads the current resolved commit and uses its source-build path. The same fallback applies when archive verification fails. This keeps the service installable while making the fallback reproducible. Open the service page's Updates panel to see Installed using, the resolved release, the selected archive when applicable, and the prebuilt fallback reason.

The practical channel behavior is:

Selector DUMB behavior
latest Resolve the current stable GitHub Release, then use its verified archive or source fallback
prerelease For the official InfiniDysk repository, follow the rc channel so a newer dev snapshot cannot be mistaken for an RC; then use its verified archive or source fallback
dev, rc, lts, edge Track the exact digit-free tag when it exists; use a matching verified release archive when published, otherwise build that tag's resolved commit
Versioned/dated tag Treat it as a fixed configured release; use its verified archive when published, otherwise build its resolved commit
Full commit_sha or branch Source build by design

Why DUMB does not unpack the Docker image

The official InfiniDysk container is Alpine/musl-based, while DUMB's runtime and managed packages are Ubuntu/glibc-based. Extracting application files from that image would also pull a runtime layout and native libraries built for a different libc boundary. The official Ubuntu-built release archives are the compatible prebuilt format for DUMB; source fallback is the compatibility path when no usable archive exists.

After a prebuilt install, DUMB starts the archive's framework-dependent native apphost against DUMB's compatible .NET runtime, even if a local .NET SDK remains from an older source build. Source installs continue to launch through the managed local SDK and application DLL.

The same revision suffix remains visible for the rolling prerelease channel and for branch, exact-commit, or other moving-tag installs. Ordinary stable release versions are shown in the frontend as their clean release tag (for example, v0.10.0); DUMB retains the resolved commit internally for download, cache, and source-integrity checks rather than presenting it as part of the stable version.

When the selected tag also has an architecture-specific InfiniDysk release archive, DUMB tries that archive first. The rolling rc GitHub Release is therefore a valid moving channel: DUMB resolves its current commit and asset digest before installing it. Branch and exact-commit selections remain source builds.

DUMB accepts the current infinidysk-<version>-linux-<arch>.tar.gz release artifact and the former nzbdav-<version>-linux-<arch>.tar.gz name. The selected asset must include a published SHA-256 digest, and its archive root must match the asset name. When both names are published for one release, DUMB prefers the name matching the configured repository. A renamed official artifact therefore uses the verified prebuilt path instead of silently falling back to a source build.

Existing installations whose marker is only dev perform one update to adopt the commit-aware marker. Tags containing any digit, such as v0.9.5, 2026.08.03, or dev2, remain pinned configured releases and do not enable scheduled automatic updates. Use Install configured release to apply those tags intentionally.

Pinning an exact InfiniDysk commit#

Set commit_sha to the complete SHA from the configured repo_owner and repo_name:

"infinidysk": {
    "repo_owner": "infinidysk",
    "repo_name": "infinidysk",
    "commit_sha": "0123456789abcdef0123456789abcdef01234567"
}

The commit pin overrides release_version_enabled and branch_enabled. Automatic updates stay disabled while the pin is present. Change the SHA to move deliberately to another revision, or clear it to return to the configured release/branch strategy.

After saving a new SHA, open Updates and select Install configured commit. This installs and restarts InfiniDysk on the saved commit. Do not use Override + latest for this operation; that action intentionally installs the latest moving release while leaving the saved pin in place for a later restart.

Source-build update safety#

Branch and exact-commit updates publish the .NET backend into a clean candidate directory, validate the complete runtime, and then replace the installed backend as one unit. This prevents assemblies removed or upgraded upstream from remaining in /infinidysk/app and being loaded alongside the new build.

After upgrading from an older DUMB version, an existing branch or commit install may rebuild once even when its Git revision has not changed. That one-time rebuild records the current source-build format and replaces any legacy overlaid output. Do not manually delete /infinidysk/app or enable clear_on_update for this recovery; use Install configured release/branch/commit and let DUMB preserve the previous backend until the replacement candidate passes validation.

clear_on_update applies only to replaceable source and runtime files. Before any clear or archive merge, DUMB automatically carries forward configured exclusions, an in-tree config_file, explicit config/data/database path fields, conventional data/db directories, root-level SQLite databases and active WAL/SHM/journal sidecars, and symlinked persistent data directories. This guard also applies when an older saved configuration omitted those paths from exclude_dirs.

Keep normal backups of application databases and configuration. The update guard prevents DUMB's installer from intentionally clearing those files; it is not a replacement for backups or application-native database recovery.

Environment Variables#

  • LOG_LEVEL: Logging level for InfiniDysk (defaults to INFO).
  • WEBDAV_USER: Override the WebDAV username (defaults to admin).
  • WEBDAV_PASSWORD: Override the WebDAV password.
  • CONFIG_PATH: Override the InfiniDysk config path (defaults to config_dir).
  • FRONTEND_BACKEND_API_KEY: Backend API key shared with the frontend.
  • ASPNETCORE_URLS: Backend bind address (defaults to http://+:<backend_port>).
  • PORT: Frontend port (defaults to frontend_port).
  • BACKEND_URL: Frontend-to-backend URL (defaults to http://127.0.0.1:<backend_port>).

Protect API keys

FRONTEND_BACKEND_API_KEY grants backend access. Treat it like a secret and avoid committing it to source control.


Integration with DUMB#

When InfiniDysk starts, DUMB performs several automation steps:

  • Syncs Arr instance details into the InfiniDysk database
  • Ensures API categories exist for Arr integrations
  • Creates /mnt/debrid/infinidysk-symlinks/<category> roots
  • Updates Arr permissions and root folders
  • Adds or updates a download client named InfiniDysk in Arr

The Arr instance list is stored in InfiniDysk’s SQLite config under arr.instances, so DUMB can merge user edits with auto-detected instances.

Startup timing

If the InfiniDysk backend is not reachable yet, DUMB retries the download-client setup shortly after startup.

Database migration startup#

DUMB starts the InfiniDysk frontend before running the blocking database migration. This is the default launch behavior and lets the Web UI show InfiniDysk's live Database maintenance in progress page, including migration steps, progress, and elapsed time, even when a large database takes a long time to migrate.

After a successful migration, DUMB starts the normal backend and the page reloads into InfiniDysk when it becomes healthy. If migration fails, DUMB keeps the frontend alive through InfiniDysk's brief failure-display window, then stops it and exits the InfiniDysk process with the migration's non-zero exit code. No separate setting is required.

Arr core_service setting#

For Sonarr/Radarr/Lidarr/Whisparr instances you want wired to InfiniDysk, set core_service to infinidysk or include it in a list:

"core_service": "infinidysk"
"core_service": ["decypharr", "infinidysk", "altmount"]

This tells DUMB to auto-configure Arr integration around InfiniDysk’s WebDAV and download-client workflows. See Core Service Routing for how core_service affects automation.

1. rclone WebDAV Mount#

Create a dedicated rclone instance for InfiniDysk and point it at the WebDAV endpoint:

"rclone": {
  "instances": {
    "InfiniDysk": {
      "enabled": true,
      "core_service": "infinidysk",
      "process_name": "rclone w/ InfiniDysk",
      "suppress_logging": false,
      "log_level": "INFO",
      "key_type": "InfiniDysk",
      "zurg_enabled": false,
      "decypharr_enabled": false,
      "mount_dir": "/mnt/debrid",
      "mount_name": "infinidysk",
      "config_dir": "/config",
      "config_file": "/config/rclone.config",
      "log_file": "/log/rclone_w_infinidysk.log",
      "zurg_config_file": "",
      "cache_dir": "/cache",
      "command": [],
      "api_key": ""
    }
  }
}

When key_type is set to InfiniDysk, DUMB configures rclone to use:

  • http://127.0.0.1:<frontend_port>/ as the WebDAV URL
  • WEBDAV_USER / WEBDAV_PASSWORD (or the values stored in the InfiniDysk DB)
  • an rclone RC listener on the first available port starting at 5572

DUMB reserves RC ports already assigned to other managed rclone instances and AltMount, and also checks active listeners before selecting the port. On first setup, DUMB enables Settings -> Rclone Server in InfiniDysk and points it at the local RC listener so WebDAV changes can invalidate rclone's VFS directory cache. Later InfiniDysk UI changes to the RC enablement, host, username, or password are preserved. A saved --rc-addr and --dir-cache-time in the rclone command are also retained when they remain valid.

Default rclone mount path (if not overridden) is:

/mnt/debrid/infinidysk

Streaming optimization#

When the backend advertises rclone_optimizer_infinidysk, open the dedicated InfiniDysk-backed rclone service page and select Rclone Optimizer. The primary job indicator, content picker, live measurements, report, apply, and rollback controls belong to rclone because those are rclone settings. The InfiniDysk page only shows a contextual link while an associated rclone test is active.

The test does pull content through InfiniDysk's authenticated WebDAV server and the configured Usenet providers. It also consumes InfiniDysk Overview and stream-trace API data while rclone RC and DUMB host metrics describe the mount and system side. Review Rclone Streaming Optimizer before testing, especially the provider traffic and concurrency limits.

2. Arr Integration (Sonarr/Radarr)#

Set core_service to infinidysk (or include infinidysk in a list) for the Sonarr and Radarr instances you want wired to InfiniDysk:

"sonarr": {
  "instances": {
    "Default": {
      "enabled": true,
      "core_service": "infinidysk",
      "port": 8989
    }
  }
},
"radarr": {
  "instances": {
    "Default": {
      "enabled": true,
      "core_service": "infinidysk",
      "port": 7878
    }
  }
}

DUMB will:

  • Create symlink roots at /mnt/debrid/infinidysk-symlinks/<category>
  • Configure InfiniDysk to recognize these paths
  • Update Arr permissions (enable chmod + set folder/file modes)
  • Attempt to add an infinidysk download client in the Arrs using their API keys

When core_service includes both decypharr and infinidysk, the root folder base shifts to /mnt/debrid/combined_symlinks/<category>. Other multi-service combinations keep the InfiniDysk symlink root unless another workflow owns its own root-folder setup.

Automatic vs manual wiring

When core_service is set to infinidysk (or includes it), DUMB automatically configures download clients, root folders, and permissions. If core_service includes both decypharr and infinidysk, the Arr root folder base switches to /mnt/debrid/combined_symlinks/<category>. Manual setup is only needed when core_service is blank or you want to override the combined workflow wiring.

Category mapping#

By default, DUMB maps Arr types to categories:

Arr service Default category
Radarr movies
Sonarr tv
Lidarr music
Whisparr whisparr

Instance names are slugified into categories if present (for example, Radarr 4K becomes radarr-4k).


Accessing the UI#

  • Navigate to: http://<host>:<frontend_port> (default port 3000)
  • WebDAV endpoint: http://<host>:<frontend_port>/

Port conflicts and auto-shift

InfiniDysk defaults (3000/8080) overlap with Riven defaults. DUMB can auto-shift conflicting ports at container startup or during the onboarding core-service start flow, updating dumb_config.json accordingly. Per-service stop/start/restart does not re-run port conflict resolution, so fix conflicts manually before restarting a single service.


Troubleshooting Tips#

InfiniDysk starts but its port is already open#

The maintained InfiniDysk fork serves a controlled migration status responder while blocking database migrations run. During that phase the backend port can accept connections, but /health returns HTTP 503 with {"status":"migrating"}. DUMB's service health shows Starting and keeps stack readiness open until InfiniDysk's real backend returns Healthy.

This is not an Auto-restart failure. Do not repeatedly restart or interrupt a legitimate migration. Open InfiniDysk's embedded UI to view its migration progress. If the state never advances, inspect InfiniDysk logs and available storage before deciding whether recovery is required.

Compare InfiniDysk performance#

Open the InfiniDysk service page's AI Assist tab and choose Performance to compare a selected window with the previous matching period or with the period before the latest DUMB-saved setting change.

In addition to generic logs and process metrics, DUMB can read the maintained fork's metrics.sqlite and db.sqlite in read-only mode. The evidence includes queue worker settings, segment success/missing/error/retry rates, provider latency, read-session activity, queue completion/failure timing, long-running queue processors, and busy-period throughput.

Use Preview bundle first to confirm native telemetry is available and check the exact coverage. These metrics do not measure Plex click-to-first-frame latency, so playback-start conclusions should remain qualified unless Plex-side timing is correlated separately.

See AI Assistant for the full evidence and safety model.

Assess SQLite pressure#

InfiniDysk currently stores its operational and metrics data in SQLite. DUMB can optionally monitor both databases from Metrics → Settings → Database Health Monitoring or the InfiniDysk service page's Database Health panel.

Start with Standard / passive mode and collect through normal imports, health checks, and playback. Use Enhanced / read-only probes when you also want bounded SQLite metadata latency. Repeated lock/busy/timeout errors, sustained WAL growth, slow probes, or network-filesystem placement are stronger reasons to investigate PostgreSQL than database size alone. See Metrics Collection for the safety boundary and interpretation guidance.

Permission changes

DUMB updates Arr media-management permissions to enable chmod operations (folder 777, file 666). If you manage permissions manually, review these settings after integration.

  • If rclone fails to authenticate, verify WEBDAV_USER/WEBDAV_PASSWORD and restart the container.
  • If Arr download clients are not created, confirm each Arr instance is enabled and has a readable config.xml for API key discovery.
  • If Arr root folders are missing, verify core_service includes infinidysk and the Arr API is reachable.
  • Every release install automatically tries InfiniDysk's matching verified Linux x64/ARM64 prebuilt archive first. If the archive is absent, has no published SHA-256 digest, fails validation, or is not available for the current architecture, DUMB keeps the live runtime untouched and automatically falls back to the source build. This behavior is inherent and has no user-facing toggle. The moving prerelease selector resolves and tracks the newest GitHub prerelease through the same GitHub prerelease-list flow used by CLI Debrid. Its installed marker is <tag>-<short-sha>; update checks resolve the current tag commit before comparing, so an unchanged prerelease is reported as current while a tag moved to a different commit remains detectable. Source fallback resolves the selected tag to its immutable commit before downloading; branch/commit installs use an on-demand managed .NET SDK. DUMB merges the InfiniDysk-specific build variables with the container environment so system tools remain available, and invokes /bin/bash explicitly when installing the SDK. An error such as No such file or directory: 'bash' indicates an image that predates this fix and should be retested after pulling a fixed tag and recreating the container.
  • Check /log for InfiniDysk startup errors, and ensure frontend_port/backend_port are not already in use.

Migration from NzbDAV#

Fresh DUMB installations use the canonical infinidysk service key, InfiniDysk process name, INFINIDYSK_* configuration prefix, /infinidysk runtime root, /mnt/debrid/infinidysk mount, and /mnt/debrid/infinidysk-symlinks library root.

Because that namespace is already canonical, a fresh installation is not migration-eligible and the dashboard does not show Review migration. The migration job API returns null until an actual guarded namespace job exists.

Existing installations are not silently moved. DUMB accepts the legacy nzbdav key, dependency tokens, paths, and NZBDAV_* variables, normalizes them in memory, and continues writing the legacy identity back to disk until the user opts in. If both top-level service keys are present, DUMB refuses to guess which entry owns the existing data.

The dashboard presents existing installations with Review migration and Remind me later. The reminder is stored by the backend, so it applies across browsers and reappears after seven days.

Create and verify an independent backup first

Before accepting either migration path, back up the DUMB configuration, InfiniDysk/NzbDAV state, Arr and Prowlarr databases, affected media-server configuration, and the symlink library to storage outside the paths DUMB will migrate. Confirm that the backup is readable and restorable. DUMB creates a private rollback bundle during migration, but that bundle is a recovery aid—not a replacement for an independent backup. The dashboard requires an explicit acknowledgement of this backup before it enables Migrate now.

The available compatibility cutover changes the persisted service identity and managed process name to InfiniDysk. It can also rename DUMB-generated attached instance/process labels such as Radarr NzbDAV to Radarr InfiniDysk. Before writing those changes, DUMB saves a private copy of the complete configuration under /config/migrations/infinidysk-backups. Saved dashboard ordering, keyboard shortcuts, and notification service filters follow any renamed process labels. It does not change:

  • /nzbdav or another existing runtime path
  • /mnt/debrid/nzbdav or /mnt/debrid/nzbdav-symlinks
  • Arr categories, root folders, item paths, tags, or tag IDs
  • Arr import-list or Radarr collection root paths
  • media-server library paths
  • existing symlink targets

The exact former DUMB repository defaults are updated to infinidysk/infinidysk so installs and updates continue to resolve; intentional custom forks remain untouched. Restart DUMB after accepting the compatibility cutover when the service is enabled.

The optional Migrate the complete InfiniDysk namespace path performs the remaining cutover as one guarded operation. It is not enabled until its preflight passes. The preflight makes no changes and checks:

  • InfiniDysk active reads can be measured;
  • InfiniDysk's effective repair.enable scheduler state can be inspected and changed through its authenticated API when necessary. An enabled value owned by an NZBDAV_CONFIG__... environment variable is a blocker: set that value to false, restart InfiniDysk, and rerun preflight so DUMB is not fighting an authoritative environment override;
  • every enabled Arr API can be inventoried. DUMB includes an Arr when its core_service metadata links it to InfiniDysk or live API inventory finds a legacy root/item path, import-list root, Radarr collection root, download-client/category reference, or nzbdav tag. This catches Prowlarr-managed Arrs whose metadata intentionally omits the InfiniDysk linkage. The preflight lists included and excluded Arr instances with the reason for each decision. Large Arr catalogs use a migration-specific 120-second API timeout; current queue entries are reported as pending quiescence rather than forcing the operator to empty every queue at the same instant;
  • every enabled InfiniDysk-linked rclone, Radarr, Sonarr, Lidarr, Whisparr, NeutArr, Profilarr, and Seerr instance is inventoried, including singular, list, and combined core_service/core_services values;
  • enabled Prowlarr instances are reachable so their Arr application connections and the shared legacy nzbdav tag can be inventoried. While an installation still uses the legacy namespace, normal DUMB setup reuses the existing nzbdav tag ID for InfiniDysk-linked applications instead of creating a competing infinidysk tag. Preflight blocks when both labels (or both legacy and canonical application names) already exist and would collide during rename. This can happen after an older failed migration attempt; reconcile the duplicate in Prowlarr, preserving the tag assignments you need, and run preflight again;
  • affected Plex, Jellyfin, and Emby activity and library APIs can be inspected. If no DUMB-managed media server is enabled and both dumb.plex_address and dumb.plex_token are configured, DUMB infers that Plex is external, verifies its server identity, and inventories its libraries through the Plex API;
  • destination paths do not contain conflicting data;
  • active mounts can be detached and every filesystem move is an atomic, rollback-safe rename; and
  • every detected legacy path is under a supported DUMB-managed root. This includes generated attached-service config and log paths such as /radarr/nzbdav and /log/rclone_w_nzbdav.log; paths outside managed roots remain blocked for manual review.

Before downtime begins, DUMB stores the complete DUMB configuration, relevant application configuration/database files, Arr, Prowlarr, and media-library API snapshots, scan-guard state, and a symlink manifest in a private mode-0700 bundle under /config/migrations/infinidysk-backups. The symlink snapshot catalogs link paths and target strings without checking target existence, so backup cannot trigger reads or metadata waits through the active rclone/FUSE mount.

These internal snapshots are designed to reverse this specific cutover. They cannot protect against pre-existing corruption, failure of the storage holding both the live data and rollback bundle, or unrelated application writes made during the migration.

When applied, DUMB first enters an automatic quiescence stage. It stops linked NeutArr, Seerr, Profilarr, and Prowlarr processes so they cannot add new Arr work. It also captures InfiniDysk's exact effective repair.enable value in the private rollback bundle, temporarily disables the internal scheduled health checks through InfiniDysk's API, and reads the value back before waiting on active reads. Health probes already in progress are allowed to finish, but the scheduler cannot continuously replace them. Each Arr remains available while its current queue drains; DUMB reports the remaining count in job progress and stops that Arr immediately after its queue reaches zero. If a failed, held, or otherwise stuck download prevents the queue from draining, use the still-running Arr UI to remove, retry, or resolve that entry while its producers remain stopped. DUMB never deletes or ignores queue items automatically. Affected media servers are handled independently. DUMB waits for playback to become idle and guards automatic scans. DUMB-managed servers are stopped as soon as they are safe. An inferred external Plex remains running because DUMB does not own its process; DUMB cancels/guards Plex scans through the API and requires it to remain idle. Pause Autoscan and any other external scan or request producer before cutover because the Plex token cannot stop those separate processes. DUMB then waits for InfiniDysk reads to drain and holds every managed stopped service through mutation and validation.

While the persisted job is waiting on verified active playback from a DUMB-managed media server, Open progress offers Stop active playback and continue. The action requires typing STOP ACTIVE PLAYBACK, immediately stops the listed media server, and therefore terminates its active streams. DUMB then waits for InfiniDysk active reads to reach zero before continuing. This override applies only to verified media playback: it cannot bypass Arr queues, unknown media/API state, active InfiniDysk reads, path conflicts, or any other safety check. Operators may instead leave the job waiting for playback to finish normally.

The playback-stop action is never offered for inferred external Plex. Stop its playback from Plex or the owning container/platform, pause Autoscan, and let the persisted job continue polling. The progress message distinguishes Arr queues, managed playback, external Plex activity, and remaining InfiniDysk reads so an active read alone is not mislabeled as a failed Arr queue.

Automatic quiescence waits up to one hour. A transient Arr API or database failure remains a visible pending condition and is retried during that window; it does not immediately trigger rollback. If activity remains, an Arr API stays unavailable through the deadline, or another non-retryable quiescence step fails, the job aborts before moving namespace paths, restores scan guards, and restarts only the processes DUMB stopped. This removes the requirement for the operator to pause every queue, automation producer, and playback session at exactly the same moment.

After a successful cutover DUMB restores and verifies the captured repair.enable value before restarting request/search producers. If any later stage fails, rollback restores the captured InfiniDysk database and verifies the same scheduler value before the job becomes terminal. The scheduler guard is recorded as infinidysk-health-check-guard.json in the private migration bundle.

After quiescence, DUMB detaches the old rclone mount, moves the runtime/mount/symlink/log paths plus discovered DUMB-managed attached-service paths, rewrites symlink targets and InfiniDysk configuration records, saves the canonical DUMB paths, and restarts the stack in provider-first order. Parent namespace moves and nested generated roots are planned separately: for example, after moving nzbdav-symlinks, DUMB still renames children such as radarr-nzbdav and sonarr-nzbdav inside the new parent. It then verifies that every planned legacy source is absent, every canonical destination has the expected type, and no raw symlink target retains the legacy namespace. Every linked service that was running before the cutover is restarted, and DUMB reruns setup for rclone, Arr, NeutArr, Profilarr, and Seerr so their generated integration state sees the canonical linkage. Services that were stopped remain stopped. Any running service whose DUMB process or instance label is renamed is also included even when its linkage is otherwise unrelated, preventing an old process from being orphaned under its former name. Generated provider category directories beneath completed-symlinks are SQLite-backed virtual paths, so DUMB rewrites the history, queue, and DAV category/path records that materialize them while the provider is stopped. Do not try to rename those paths through the live FUSE mount. The database is part of the private rollback bundle. DUMB then updates and verifies configured or live-reference-discovered Arr root folders, existing movie/series/artist paths, import-list roots, Radarr collection roots, managed download-client names/categories, Arr tag labels (without changing tag IDs), Prowlarr Arr application names and core-service tag labels (also without changing IDs), and Plex/Jellyfin/Emby library paths. Compatible Arr builds receive bounded bulk-editor batches for root-prefix-only item changes; unsupported editor APIs fall back to exact per-record updates. When a supported bulk editor reports a conflict, DUMB bisects that batch to isolate the conflicting records instead of converting an otherwise large catalog into hundreds or thousands of serial API writes. DUMB validates every resulting API item path and requires the canonical filesystem path for every file-bearing Arr item and every changed list/collection root before continuing, so a partial or incompatible bulk result still fails into the normal rollback path. The job reports completed/total counts for the current Arr and across all affected Arrs instead of holding one percentage for an entire large catalog. Plex identity, scan-guard, inventory, and library-path operations use an extended API response window because large servers can respond slowly during cutover. If a Plex library update times out after submission, DUMB does not blindly submit it again: it reconnects and accepts the change only when the library exposes the exact requested path set. An unverifiable result still fails into rollback.

Do not manually change Arr roots or scan a media library while the job is still running. DUMB keeps media-server scan guards in place until canonical Arr item directories and media-library paths have passed these checks. After the job reports success, confirm the new roots contain the expected symlinks, then run the normal Arr and media-server scans. Keep automatic trash/deletion disabled until the refreshed libraries and sample playback are verified.

Arr's Update All action refreshes existing records; it does not change root folders, import-list roots, or Radarr collection roots. If manual recovery is required after an older migration, use the Arr root-folder change workflow and choose No, I'll move the files myself because DUMB already moved the symlink library. Update import lists and Radarr collections separately before scanning, then run Update All only as the follow-up refresh.

After the full migration succeeds#

Do not start this checklist unless the result is Namespace migration completed. A rolled-back, interrupted, or attention-required result needs its recovery details reviewed first.

  1. Confirm InfiniDysk, its rclone mount, every affected Arr, Prowlarr, and the affected media server report healthy.
  2. Open each affected Arr and confirm its canonical root is populated, sample existing items use the infinidysk-symlinks path, and System → Health has no missing-root or download-client path warning.
  3. Open the Arr's main library page and click Update All in its top toolbar: Movies → Update All in Radarr, Series → Update All in Sonarr, Artists → Update All in Lidarr, or the equivalent main-library Update All action in Whisparr. This is the circular-arrows refresh action beside the main library controls—not a System task or root-folder edit. Do not use Change Root Folder or ask Arr to move files after a successful migration—DUMB already updated the roots, existing item paths, import-list roots, and Radarr collection roots and moved the managed symlink namespace.
  4. In Prowlarr, confirm the affected Arr applications connect and the canonical infinidysk tag is present where the legacy nzbdav tag was used.
  5. Keep automatic trash/deletion disabled, then scan the affected Plex/Jellyfin/Emby libraries. DUMB updates and verifies their paths but does not start the scans.
  6. Compare expected library counts, inspect several items, and test playback plus seeking for at least one movie and one episode.
  7. Only after those checks pass, restore the operator's preferred automatic trash/deletion behavior. Retain the independent backup and DUMB rollback bundle for a suitable observation period.

The compatibility-only migration keeps all paths unchanged. After that path, verify InfiniDysk starts, attached services reconnect, and existing playback works; an Arr or media-library scan is not normally required.

If a stage fails, DUMB stops the partially migrated stack, restores paths and saved files with their captured ownership and permissions, reapplies and validates the previous Arr/Prowlarr/media-library references, removes every Arr root path created only by the failed direction, and restores the exact captured symlink targets after the original symlink roots are back in place. Missing symlink roots, restore errors, target mismatches, or obsolete Arr roots make rollback report that attention is required rather than claiming recovery. Rollback restarts the original process names and publishes its own path, symlink-catalog, configuration, service, Arr, Prowlarr, media-library, and scan-guard progress stages. A terminal rolled-back job finishes at 100% and retains a redacted root-cause message; 100% means the recovery workflow finished, not that the requested cutover succeeded. When rollback needs attention, the dashboard lists the sanitized component errors and retained backup/config paths. Inspect those details and verify the legacy stack before performing a targeted restore; do not blindly restore the complete bundle or rerun the migration.

Older DUMB builds did not retain file ownership metadata in this rollback manifest. If an older rollback reports that InfiniDysk/NzbDAV cannot read its configuration path, inspect the owner and mode of the named database and its SQLite -wal/-shm sidecars. Restore only the affected files to the configured PUID/PGID and their prior restrictive mode before restarting DUMB; do not recursively change ownership across the blob, mount, or symlink trees.

Combined relationships remain combined: for example, decypharr, nzbdav becomes decypharr,infinidysk; DUMB does not discard the Decypharr relationship. Zurg is deliberately not an InfiniDysk migration consumer. Its core_service field is used by other workflows and does not make Zurg part of this cutover.

The complete cutover runs as a backend-persisted background job. The migration dialog shows the current stage, percentage, and recent stage history. Closing the dialog or navigating to another page does not cancel the job; a persistent InfiniDysk migration running banner shows the latest progress and reopens the dialog. Reloading the dashboard or signing in from another browser/device reattaches to the same backend-owned job. If a browser observes it finish while the dialog is closed, that browser shows a dismissible result banner once. A terminal job first discovered after a later reload, sign-in, or focus event is not announced again as a new completion; its persisted result remains manually reopenable from the InfiniDysk service page.

The live job record and full preflight inventory are stored as separate private mode-0600 sidecars under /config/migrations. This keeps job-status polling small and responsive even when the rollback inventory contains tens of thousands of Arr records; polling never rewrites the complete inventory.

Do not restart the DUMB container while the migration is active. A backend restart cannot safely resume an in-process filesystem/API cutover, so DUMB marks the retained job interrupted and directs the operator to inspect its private backup bundle and current service paths before retrying. Normal dialog closure and dashboard navigation do not interrupt it.

The final paths are /infinidysk, /log/infinidysk.log, /mnt/debrid/infinidysk, and /mnt/debrid/infinidysk-symlinks. Historical snapshot filenames are retained; future scheduled snapshots use infinidysk-{timestamp}.json. DUMB intentionally does not launch Arr or media-server scans after success. Review service health, then scan the affected libraries so their availability state is refreshed.

Preflight must be current

A passing preflight expires after 30 minutes. DUMB repeats structural/API checks before starting and then owns the live quiescence window. Queue, playback, and active-read activity shown as pending conditions does not invalidate the preflight; it must drain during the one-hour automatic quiescence stage before DUMB moves any path. The explicit playback-stop action interrupts viewers but does not waive the active-read drain.


Resources#