Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Crash · flash cache

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.

ESP32ESP32-CAMESP32-S3Updated 3 Nov 2026

Community draft — report a mistake

What you see

OutputOutput
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. 1

    Add IRAM_ATTR to every interrupt handler

    void IRAM_ATTR onButton() { ... }. Any function the ISR calls needs IRAM_ATTR too.

  2. 2

    Keep ISR data in RAM

    A const table read by the ISR lives in flash. Declare it DRAM_ATTR const uint8_t table[] = {...}; or copy it to a normal array at startup.

  3. 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. 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.

↑↓ to move · Enter to open