Bricked Playdate (h7d1, 2.4.2) β€” recovery says "Invalid bootloader file"

Hi everyone,
I'm hoping someone here has been through this and can point me in the
right direction.

My Playdate (serial Y067308) got stuck in a boot loop a while back - the
"Your Playdate needs to restart, press A" screen, on repeat forever. I
opened a ticket with Panic, and they were really helpful at first: they
sent me a 2.6.0 .pdos and a .pdkey tied to my serial.

So I poked. Here's where I ended up:

The device isn't fully dead - over USB serial it talks back fine.
version confirms it's on 2.4.2 with crashed=1, and the help command
lists everything I'd expect (bootdisk, datadisk, fwup, etc.). But the
Lua VM is completely gone - luatrace is empty, memstats actually
crashes the device, and the crashlog has the same usage fault at
pc:24057248 every single boot. It always lands in exactly the same
place, which makes me think it's corrupted bytecode somewhere in the
system files, not user data.

I tried the obvious stuff first: factoryreset and formatdata both
ran cleanly, but the crash didn't budge. So whatever's broken isn't in
/Data - it's deeper, in System or pdfw.

Then I went the recovery route. The A+B+Menu+Lock combo works fine and
mounts BOOTSY. I tried three things:

  • Putting the .pdos zip + .pdkey on BOOTSY β†’ "Applying system update"
    animation plays, then it silently goes back to the crash screen
  • Unpacking the bundle and putting boot/pdfw/System/etc. on BOOTSY β†’
    it actually shows me an error this time: "Invalid bootloader file"
  • Leaving BOOTSY empty β†’ recovery still tries to install something from
    some embedded copy, and that also fails

That "Invalid bootloader file" felt like a real clue, so I went looking
on the forum and found Dan Wineman's old reply
here:
basically, when you skip too many versions, the bootloader format
changes and recovery can't accept the new bundle directly - you have to
install an intermediate version first that does the filesystem
transition. Mine looks like exactly that: 2.4.2 recovery is rejecting
the 2.6.0 boot file's signature/format.

So that's where I'm stuck. To get out of this I think I need an
intermediate .pdos somewhere in the 2.4.x or 2.5.x range that my
2.4.2 recovery will accept. Once I'm on that, I can chain up to 2.6.0
the normal way.

Couple of things I'd love help with:

  1. Has anyone hit the same gap (2.4.x β†’ 2.6.x) and figured out which
    intermediate version actually works for h7d1?
  2. Anyone from Panic who'd be willing to look at this and send the
    intermediate? The bundle would be signed and tied to my serial via
    the .pdkey they already issued, so it's not like I'm asking for
    anything redistributable.
  3. If this isn't recoverable through the recovery partition at all and
    I genuinely need to go JTAG/SWD, I'd appreciate a heads-up so I can
    stop chasing software fixes.

Happy to share full serial transcripts, the crashlog, or anything else
that'd be useful. Everything's on hardware I own - just trying to get
my Playdate back.

Thanks for reading.

Think of how much time you would have had to do something productive or enjoyable if the system just worked…

1 Like

Oh, I didn't see your post. Tell me, did they help you in the end?

Hey Denis, sorry I missed your post! Usually you'd use the Playdate Utility app to copy the pdos and pdkey files to the Playdate and trigger the update but since you're comfortable with the serial commands let's just do that. First, are you able to get to the data disk with the datadisk command? If not.. well, let's skip that for now because it's a whole other can of worms. So when (if) you have the data disk mounted, copy the pdos and pdkey files to the data disk and eject the disk. After the device has rebooted run fwup /<filename.pdos> /<filename.pdkey> on the serial port to trigger the update.

If you can't open the data disk, is it rebooting to the crash screen instead? Or to the boot disk?

What I think happened is you unzipped the pdos file and tried to apply the boot file in there, but it hadn't been decrypted yet; hence "invalid bootloader file". As for the lua stuff looking weird, I don't think the system is even getting into the lua runtime yet at that point.

There shouldn't be any problem upgrading directly from 2.4.x to 2.6.0, ftr. The last update marked "must pass through" in memfault is 2.2.0.

Let me know how it goes! And again, apologies for the delayed response

Thanks for getting back to me! new finding:

datadisk works fine - datadisk command reliably reboots into the data disk (mounts as PLAYDATE on Windows). No issues getting in or out
of data disk mode. Serial comes back cleanly after pressing A.

I followed your exact flow:

  1. datadisk via serial β†’ mounted on E:
  2. Copied Playdate-h7d1-2.6.0-176236_bcbf4fed.pdos + PDU1-Y067308.pdkey
    to the root of the data disk (not /Staging, not unzipped β€” just
    the raw .pdos zip and the .pdkey as-is)
  3. Pressed A on the device to eject
  4. Device rebooted back to the "press A to restart" screen
  5. Over serial: fwup /Playdate-h7d1-2.6.0-176236_bcbf4fed.pdos /PDU1-Y067308.pdkey

Result: serial port drops ~2 seconds after sending the command, no
output captured, device silently reboots back to the same crash screen.
Version stays at 2.4.2, crashed=1.

For completeness, also tried via PlaydateUtility - same outcome. It connects, sees the device, accepts the .pdos
and .pdkey, starts the firmware update flow, the device reboots into
data disk mode, but the update never actually progresses. Same end
state: stuck on 2.4.2 with the crash screen.

Now the new finding. After your reply I went back and checked
/crashlog.txt on the data disk after an fwup attempt. Right at the
timestamp we ran fwup, there's a fresh crash entry that looks completely
different from the usual repeating Lua crash:

--- crash at 2026/04/22 21:21:57 ---
build: 5cd9814a-2.4.2-release.166897-buildbot
r0: 0x00008001 r1: 0x200027b0 r2: 0x24000b41 r3: 0x00000000
r12: 0x00000002 lr: 0x24021c03 pc: 0x24021c02 psr: 0x41000000
cfsr: 0x00010000 hfsr: 0x40000000 mmfar: 0x00000000 bfar: 0x00000000
rcccsr: 0x00000000
heap allocated: 0
Lua totalbytes=0 GCdebt=0 GCestimate=0 stacksize=0

Key differences from the usual boot-loop Lua crash:

  • pc: 0x24021c02 - a completely different code address (the Lua crash
    is consistently at 0x24057248)
  • cfsr: 0x00010000 - UsageFault with INVSTATE bit set
  • hfsr: 0x40000000 - forced hardfault
  • heap allocated: 0, Lua totalbytes=0 - fires before heap or Lua
    init, i.e. very early in the fwup code path
  • r12=0x00000002, pc=0x24021c02 (even, not Thumb-aligned) - looks
    like an ARM/Thumb state mismatch or a bad function pointer

This happens immediately on fwup invocation, which is why the port
dies in ~2 seconds with no error output - it's a hard fault, not a
normal reboot.

So the issue seems deeper than "2.6.0 bundle won't apply" β€” the fwup
code path itself is faulting in pdfw before it can read the files.
That's consistent with what we're seeing in recovery mode too (the
A+B+Menu+Lock combo: animation plays, then silently reverts, no flash
actually happens).

Thanks again for the help

One more idea while I'm poking around - would you be willing to send the
unlock key for my serial (PDU1-Y067308)?
The reason I'm asking: per the reverse-engineering notes, an unlocked
console exposes peek, dump, memiomd5, etc. over serial. If the
fwup hardfault really is from a bit-flip in pdfw (which is what the
even-address PCs and the a5a5a5a5 stack scrub in a live register
seem to point to), I could memiomd5 the code regions around
pc:0x24021c02 and pc:0x24031946 and compare against the matching
offsets in the 2.6.0 pdos you sent me - that would nail down whether
it's truly flash corruption and exactly where. Much better diagnostic
than what I can do today.

Normally I wouldn't ask for this - I get that unlock is intentionally
gated. But in this case the key is device-specific to Y067308, so
there's no meaningful leak risk (useless on any other unit), and if it
turns out the corruption is isolated I might be able to poke the bad
bytes back to their correct values directly, which beats JTAG as a
recovery path by a wide margin.

Totally understand if that's a hard no; just wanted to put it out
there. Either way, thanks for the help so far.

ftr for anyone else having problems like this I believe 3.0.6 fixes the underlying problem, caused by a bad game list cache file. If you're reading this in the future and still having trouble, DM me and I can send a firmware image that works around it.