Fix “Cache disabled but cached memory region accessed” on ESP32
An interrupt ran code or read constants from flash while flash was busy (saving Preferences, SPIFFS, OTA). Put the ISR in IRAM and its data in DRAM.
Community draft — report a mistake
What you see
Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed).
Core 1 register dump:
PC : 0x400d15a8 PS : 0x00060034 A0 : 0x80081004 A1 : 0x3ffbe7a0
A2 : 0x00000001 A3 : 0x3ffbdd5c A4 : 0x00000000 A5 : 0x00000001
...
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace: 0x400d15a5:0x3ffbe7a0 0x40081001:0x3ffbe7c0 0x40085c6d:0x3ffbe7e0 0x4008a2f6:0x3ffb1d40
ELF file SHA256: 2a91c0ce81e4b7f3
Rebooting...Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed). Core 1 register dump: PC : 0x400d15a8 PS : 0x00060034 A0 : 0x80081004 A1 : 0x3ffbe7a0 A2 : 0x00000001 A3 : 0x3ffbdd5c A4 : 0x00000000 A5 : 0x00000001 ... EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000 Backtrace: 0x400d15a5:0x3ffbe7a0 0x40081001:0x3ffbe7c0 0x40085c6d:0x3ffbe7e0 0x4008a2f6:0x3ffb1d40 ELF file SHA256: 2a91c0ce81e4b7f3 Rebooting...
ESP32 code normally runs from external flash through a cache. While the chip writes to flash (saving settings, a file, an OTA update), that cache is switched off. Only code and data already in internal RAM can be touched.
If an interrupt handler lives in flash, or reads a constant from flash, and fires during that window, the CPU panics with this message. Marking the handler IRAM_ATTR and keeping its data in RAM fixes it.
Quick fix — try in order
- 1
Add IRAM_ATTR to every interrupt handler
void IRAM_ATTR onButton() { ... }. Any function the ISR calls needs IRAM_ATTR too. - 2
Keep ISR data in RAM
A
consttable read by the ISR lives in flash. Declare itDRAM_ATTR const uint8_t table[] = {...};or copy it to a normal array at startup. - 3
Don't call library functions from the ISR
Serial.print, digitalRead on some cores, String, millis-based helpers and most libraries live in flash. Set a flag in the ISR and do the work in loop().
- 4
Decode the backtrace
The address that is not in IRAM (0x400d…/0x42…) is the function that was in flash. Add IRAM_ATTR to it or stop calling it from the interrupt.
Why it happens
Why only sometimes?
The crash only happens when an interrupt fires at the exact moment flash is being written — saving Preferences/EEPROM, writing SPIFFS/LittleFS, an OTA update, or Wi-Fi storing credentials. Everything works until those two coincide.
What does “cache disabled” mean?
Code in flash runs through a cache. While flash is being written, the cache is switched off and only code and data in internal RAM can be used. Your ISR tried to use flash during that window.
Arduino timer and PCNT interrupts
Hardware timer callbacks (timerAttachInterrupt) follow the same rule: IRAM_ATTR on the callback and anything it calls.
Board-specific notes
ESP32-S3: Same rule; addresses in flash start with 0x42 on the S3 instead of 0x400d.
Did this fix it?
Thanks — that helps us keep this page right.