Database corruption after overnight backup validation (ref#8QL8IV)

Hi! What’s not quite right with Roon?

· None of the above quite fits

None of the above quite fits

· None of these quite match

Tell us what's going on

· Database corruption after overnight backup validation

I experienced a Roon database corruption event on July 25.

Around 2:01 AM, the scheduled database backup started. During the backup validation, Roon reported:

corruption detected: Source array was not long enough

Immediately afterward, the Core entered a DatabaseCorrupt state and would no longer load the database. The logs repeatedly report DatabaseCorrupt until I restored a backup.

I restored the July 21 backup. The Core now starts, but the logs immediately show repeated metadata decoding errors for the same TIDAL track:

* trackid 17884584
* MetadataService2_CreditFormatter
* TrackFormatter
* code is invalid: code:55 format:positive fixint

This suggests the restored database still contains the problematic record.

Could you please determine:

1. Whether this is a known database or TIDAL metadata corruption issue.
2. Whether trackid 17884584 is responsible for the repeated decode errors.
3. Whether the corrupted object can be removed or repaired without rebuilding the entire database.
4. Whether the validator incorrectly marked the entire database as corrupt, or whether there is evidence of broader database corruption.

Tell us about your home network

· TPLINK Archer AX21

Hi @rohan_stevens,

Thank you for your post.

We need to take a step back from these immediate, more specific question because database corruption doesn’t occur without some external factor putting the database in the wrong condition at the wrong time. If we don’t identify why this happened, it’s likely just going to occur again.

Roon checksums every database object individually; if the server detected corruption during background work, then it means that an object in your database changed without explanation between indexings. That’s not really normal.

What happened just before this occurred? Did you have a power outage of any other physical event that might have triggered an unsafe shutdown? Did you add anything new to the library, or change any of the locations hosting any locally-store media (like adding a new network share, deleting an old one, etc)? What about importing content?

Logs from the most recent restore do still show corruption. The quick solution here is to restore your oldest Backup and see if you still spot any discrepancies or errors with the library. If that Backup was safe, then test the second oldest. Move forward until you can definitively spot corruption starting. This will be the start of the “unsafe” Backups.

Hi Connor,

Quick note on my setup for context, since it’s relevant to the memory-pressure angle below: I’m running Roon Core on a Small Green Computer sonicTransporter i5 (no internal drive, purchased in 2019), streaming exclusively via TIDAL — no locally-stored library, no network shares. The only endpoint involved is a Lyngdorf TDAI-1120. Nothing about this setup changed around Jul 25 — no new hardware, no new shares, no imports.

Given this is the entry-level 2019 i5 unit rather than the higher-RAM i7/Gen3 models, I want to specifically rule in or out whether my hardware’s RAM allocation is simply undersized for my current library and usage — more on that below.

I went through the full log bundle and I think I found the actual trigger. Walking through it in order:

1. What happened at the moment of corruption
At 02:01:30 on Jul 25, the scheduled backup began validating the database. Six seconds later, at 02:01:36, the log shows a GC (garbage collection) pause of 5,117ms — meaning the Core process froze for just over 5 seconds. At 02:01:39, the instant it unfroze, two things happened in the same second: my Lyngdorf endpoint dropped its connection, and the validator threw “Source array was not long enough” — which is what triggered the DatabaseCorrupt flag.

2. Why that sequence matters
A 5-second freeze happening in the middle of a database read is exactly what would produce a torn/incomplete read — the validator was partway through reading a record when everything stopped, and picked up an incomplete buffer when it resumed. That would explain the corruption without requiring any external cause.

3. This wasn’t a one-time fluke
The same signature — GC pauses of 6,000–7,500ms, recurring every ~15 seconds for up to an hour at a stretch — shows up repeatedly in the days before this happened: Jul 24 from 1:05–1:59 AM, then again at 8:37 AM, 12:37 PM, and 4:36 PM, and again Jul 25 from 8:47–8:52 AM. Every one of those episodes also coincides with my Living Room zone getting destroyed and recreated — the same disconnect/reconnect pattern as the corruption event, just without a database validation running at that exact second to catch a bad read.

Conclusion: this points to the Core — running on this 2019 sonicTransporter i5 — periodically running under enough memory pressure that it freezes for several seconds at a time, multiple times a day. July 25th at 2:01 AM wasn’t a special event; it’s just the one time this recurring freeze happened to land during a validation pass instead of during normal playback, so it corrupted the database instead of just dropping a zone.

Given that, the trackid 17884584 metadata error seems unrelated — it’s been showing up in my logs since at least Jul 20, five days before the corruption, on its own separate schedule.

A few questions given this:

  1. Can you confirm this GC-pause pattern from your side and tell me whether it points to a memory leak, an undersized RAM allocation for my library on this hardware, or something else? Given this is a 2019 base i5 unit, I’d like to know if it’s simply underspecced for Roon’s current requirements.
  2. If the corruption really is a torn read from a single validation pass, is there a way to repair just that one record instead of rolling back to an older backup?
  3. What would you recommend to stop the underlying freezing, since restoring backups doesn’t address that?

Happy to send whatever else would help — just let me know.

Thanks,
Rohan

Hi Connor, just wanted to share an observation from my end. I realized my automated backups were previously writing to the system root directory rather than my external USB drive. Could filling up that system partition space be what was causing the heavy resource strain, memory pauses, or the freezing issues during the overnight validation? I’ve since moved the backups over to the USB drive, but I wanted to see if you and the team think that root backup path could have contributed to what happened.

Hey @rohan_stevens,

Thanks for the additional information! This is a great write-up, and your post 4 is almost certainly the key to the whole thing.

On the sonicTransporter, your Roon database and the OS live on the same internal system partition. With automated backups writing to the system root, that partition was steadily filling up. A backup write plus validation pass running against a full (or nearly full) system partition is one of the most reliable ways to produce exactly the failure you saw, an incomplete/torn read, which is what “Source array was not long enough” indicates. This is the external factor @connor mentioned earlier; it fits far better than anything to do with library size.

So I wouldn’t rush toward a hardware change yet. Let’s confirm free space first: can you tell me the current available space on the system partition now that backups are on the USB drive?

Your read on trackid 17884584 is correct, that’s a benign TIDAL metadata decode issue (a credit-format quirk on TIDAL’s side), it predates the corruption, and it isn’t a sign your database is damaged. You can safely set it aside.

On your specific questions: there’s unfortunately no way to repair a single record in place, restoring a clean backup is the only supported path.

So the plan is: keep backups on the USB drive (done :white_check_mark:), confirm the system partition has healthy free space, then do the backup walk, restore your oldest backup, check for errors, and move forward one backup at a time until you find where corruption first appears. Everything before that point is your clean set.

Once you send the current free-space figure, we can confirm whether we’ve fully closed this out. :+1:

Hi Benjamin,

I looked through the sonicTransporter v2.8 web interface but couldn’t find anywhere that reports the free space on the system partition. I’m currently working from an iPad, so I don’t have an SSH client available to run df -h.

I should also mention that before moving the backups to the USB drive, I deleted several older Roon backups that were stored on the root/system drive to free up space.

Is there a way to retrieve the current free-space information through the web UI, or is there another method you’d recommend?

Hi @rohan_stevens,

I dug into this and can confirm your read: on sonicTransporter 2.8 there’s genuinely no free-space or disk-usage readout anywhere in the web interface, not under Apps, Software Manager, or Settings. So we’ll need to get the number another way. Two good options from an iPad:

Option 1, Free SSH app (recommended). @Suedkiez suggestion above is the right call. Install Termius (or Blink/a-Shell), all free on the iPad, and SSH into the sonicTransporter’s IP address. Then run:

df -h

Look at the row for the root partition, mounted at /. The Avail column is your free space and Use% is the percentage used. That one line is exactly what we need. (You can find the unit’s IP on

next to the Manage button.)

Option 2, Ask Small Green Computer. Since the disk layout and OS are on SGC’s side, their support can read the partition usage remotely and will know this hardware best. Worth a quick note to them in parallel if the SSH route is inconvenient.

Two things worth confirming while you’re in there:

First, the old backups you deleted from the root/system drive, that was the right move and should have freed real space. Good to verify with df -h that it actually did.

Second, make sure nothing is still writing new backups to the system drive. In Roon, check Settings → Backups and confirm the scheduled job now points only to the USB drive, so the system partition can’t quietly refill and put us back where we started.

Once you send the df -h output for / (or SGC’s figure), we can confirm this is fully closed out and move on to the backup walk, restore your oldest backup, check for errors, and step forward one at a time until corruption first appears. :+1:

Hi @rohan_stevens,

Just checking in on this. Were you able to try the SSH route from an iPad with Termius, Blink, or a-shell and run df -h on the sonicTransporter so we can see the free space on /? If that’s easier, we can also work from the figure Small Green Computer gives you, and it would be good to confirm in Settings → Backups that the scheduled backup is pointing only to the USB drive so the system partition does not fill back up.

Please note, if we don’t hear back from you this thread may close automatically soon. If the thread auto-closes and you need further assistance, please submit a reopen support request via the technical support help form below and specify that the issue should be reopened. Thank you.