Tidal Authentication Fails on Roon Server Restart in Version 2.60 (ref#54HHXX)

What is the operating system of your Roon Server host machine?

· Linux Server (Ubuntu, Fedora, ArcLinux...)

What kind of device are you using to perform the login?

· Android

Where are you trying to login?

· I can't log into TIDAL or KKBox

Have you been redirected to the Tidal/KKBOX login page in your browser?

· Yes

Please try clearing the browser cache and cookies for the [l](https://account.roon.app/)ogin page where you have been redirected

· No, the issue remains the same

Content / Popup Blockers

· No, the issue remains the same

Temporarily try to use a different browser

· No, the issue remains the same

Please try to restart your Roon Server by closing the Roon Server app in the taskbar (MacOS), task manager (Windows) or rebooting your Roon Server machine.

· No, the issue remains the same

Different device

· I am able to switch to the diffrent device

Are you still facing the issue on the different device

· No, the issue remains the same

Record the timestamp

· The issue occurred on March 3, 2026 between 03:50 and 03:55 AEDT (UTC+11). Roon Server restarted at 03:50:54 AEDT and Tidal entered UnknownError state at 03:54:42 AEDT. I don't need to reproduce it — I have the full logs from that session already captured.

Describe the issue

Roon Version: 2.60 (build 1629) production
OS: Linux (Docker on Unraid 7, kernel 6.12.54-Unraid)
Container: mackid1993/docker-roonserver:latest
Issue started: Roon 2.60. Did not occur with previous versions.


DESCRIPTION

Every time Roon Server is restarted (Docker container update, Unraid array restart, etc.) Tidal authentication breaks and never recovers on its own. The Tidal module enters UnknownError state permanently. Metadata Improver also shows "paused" as a side-effect.

This did not happen before Roon 2.60.


STEPS TO REPRODUCE

1. Have Roon Server running with Tidal logged in and working
2. Restart the Roon Server process (any reason)
3. Roon starts up - machine allocation succeeds, account login succeeds
4. Tidal silently fails and shows "Login failed" in the app


WHAT HAPPENS IN THE LOGS

At startup, Tidal tries to refresh the stored OAuth token:

[tidal] transition loginstatus from NoAccountConfigured to StartupWithCredentials

The oauthcb refresh endpoint then times out (30 seconds x 3 attempts):

GET https://api.roonlabs.net/oauthcb/3/tidal/refresh?token=eyJ... timed out after 30010 ms
GET https://api.roonlabs.net/oauthcb/3/tidal/refresh?token=eyJ... timed out after 30058 ms
[tidal] transition loginstatus from StartupWithCredentials to UnknownError
[tidal] transition loginstatus from UnknownError to AttemptingLogin
GET https://api.roonlabs.net/oauthcb/3/tidal/refresh?token=eyJ... timed out after 30008 ms
[tidal] transition loginstatus from AttemptingLogin to UnknownError

Or returns 401 on subsequent restarts:

GET https://api.roonlabs.net/oauthcb/3/tidal/refresh?token=eyJ... returned after 289 ms, status code: 401

Which then crashes the Tidal state machine with a NullReferenceException:

Critical: scx: System.NullReferenceException: Object reference not set to an instance of an object.
at Sooloos.Broker.Tidal.Module._TransitionStatus(_LoginStatus new_status, LoginResult login_res, Boolean save_accountdata)
at Sooloos.Broker.Tidal.Module.<>c__DisplayClass100_2.b__4()

Note: accounts5/accounts/3/machineallocate and accounts5/accounts/3/login both succeed
immediately (200 OK, ~300ms) during the same startup. Only the oauthcb Tidal refresh fails.


BUG 1 - oauthcb/refresh fails on startup

The stored Tidal refresh token (in the tidal_account file) can no longer be refreshed after
a server restart. The token was valid before the restart (Tidal was working), but the oauthcb
endpoint either times out during the startup network burst or returns 401.

This did not happen before 2.60. Manually deleting tidal_account and doing a fresh OAuth
login fixes it, proving the stored token itself is not the problem - the refresh endpoint is
rejecting or not responding to it.


BUG 2 - NullReferenceException in _TransitionStatus

When oauthcb/refresh returns an unexpected 401, the Tidal module crashes with an unhandled
NullReferenceException at Sooloos.Broker.Tidal.Module._TransitionStatus. The code path calls
_TransitionStatus with a null login_res that is not null-checked. This leaves the Tidal module
permanently broken for the session with no automatic recovery - a full restart is required.


BUG 3 - Windows app embedded browser fails Tidal OAuth redirect

When clicking "Connect Tidal" in the Roon Windows app, the embedded browser opens and login
appears to succeed, but Roon reports "failed to connect, unauthorised." Using a phone or
external browser for the same OAuth URL works correctly every time. Likely a regression from
2.60's code signing changes affecting the OAuth redirect handling in the embedded browser.


CURRENT WORKAROUND

1. Stop Roon Server
2. Delete /RoonServer/Database/Registry/Core/tidal_account
3. Delete /RoonServer/Database/Registry/Core/tidal_storage_sync_version_* (newest file)
4. Start Roon Server, wait ~2 minutes for machine allocation to complete
5. Log into Tidal - must use phone or external browser, NOT the Windows app


ADDITIONAL CONTEXT

- Machine identity (.rmembid) is stable across restarts - this is not a machine ID issue
- The oauthcb timeout correlates with a burst of parallel HTTPS connections at startup;
devicedb image requests show SSL errors ("The SSL connection could not be established")
in the same window, suggesting a startup connection pool issue
- Roon 2.60 was described as "an out-of-cycle release addressing a potential security issue
by changing code signing requirements" - this change appears to have altered how Tidal
OAuth sessions are validated at startup

Describe your network setup

ISP: Launtel (Australia), 1Gbps fibre connection
Router/switching: Ubiquiti UniFi (all wired, no Wi-Fi involved)
All Roon-related devices are connected via wired ethernet only.
Roon Server runs in a Docker container on an Unraid server.

Hey @Greg_Bobbery ,

Running Roon in a VM or Docker is not an officially supported environment. It is considered Tinkering. Roon doesn’t prevent customers from experimenting with our software in unsupported environments; however, when you do so, you also take on the ongoing support and troubleshooting for that environment.

We wanted to provide a brief explanation before moving this [thread/post] to the Tinkering section. Hopefully, other customers who may also be using your environment can help you with diagnosing and resolving your issue.

If this does not work for you, then I would recommend running Roon in an officially supported environment for the stability and support you are looking for.

Thanks for the response. I understand Docker is not officially supported,
but the three bugs I reported are in Roon’s own code, not Docker-specific:

  1. The NullReferenceException in Sooloos.Broker.Tidal.Module._TransitionStatus
    is a null reference that would crash regardless of platform - the code
    doesn’t null-check login_res before using it.

  2. The oauthcb/3/tidal/refresh endpoint timing out or returning 401 is a
    server-side issue between Roon Labs’ API and Tidal’s OAuth - the transport
    layer (Docker, Nucleus, bare metal) is irrelevant.

  3. The Windows app embedded browser failing the Tidal OAuth redirect has
    nothing to do with the server environment at all.

Happy for this to live in Tinkering, but these are application-level bugs
that will affect any Roon install if the network is slightly slow during
startup. Hopefully the stack traces are useful to the dev team regardless
of which section the thread is in.

Hi @Greg_Bobbery

Thanks for the detailed analysis. While the code paths you’re pointing to do exist, the conditions required to trigger them are largely created by unsupported environments like Docker, particularly around startup timing, networking, and concurrency. In supported setups, these paths are not exercised in a way that produces the behavior you’re seeing, which is why QA coverage and support are scoped accordingly. This can no doubt be more graceful so we’ve passed this information along.