ESP32 LittleFS Mounting Failure

I'm running into an issue with LittleFS on an ESP32 dev board where the file system refuses to mount due to corruption and tried recovery methods but did not work.

So basically, I am using LittleFS to store data of course. After powering the board down for a few hours and turning it back on, files stopped saving. The Serial Monitor now outputs the following error on boot:
esp_littlefs: ./managed_components/joltwallet__littlefs/src/littlefs/lfs.c:1384:error: Corrupted dir pair at {0x0, 0x1}

And has failed to mount.

What I've Tried So Far:

  • Enabling the "Erase All Flash Before Sketch Upload" option in the Arduino IDE.
  • Running the standard LittleFS example test code.
  • Manually erasing the flash using esptool.py (esptool.py erase-flash).
  • Changing the partition scheme in the Arduino IDE (tried Default 4MB with SPIFFS, No OTA, etc.).

Despite completely erasing the flash, the exact same Corrupted dir pair at {0x0, 0x1} error reappears immediately when trying to mount the file system.

Has anyone encountered a solution for this? Any help would be appreciated!

Hi, which ESP32 board is it actually? WROOM? C6? S3?

You will not get good answers until you provide the wiring diagram (your actual wiring, not instructions) and all the source code, Auto Formatted and in a code block. Also, any Serial output should be in a code block.

I think this does not need any wiring diagram since LittleFS runs on internal memory of the ESP32. As I mentioned I tried using the LittleFS test code which is:

#include <Arduino.h>

#include "FS.h"
#include <LittleFS.h>
/* You only need to format LittleFS the first time you run a

   test or else use the LITTLEFS plugin to create a partition

   If you test two partitions, you need to use a custom

   partition.csv file, see in the sketch folder */

//#define TWOPART




#define FORMAT_LITTLEFS_IF_FAILED true


void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {

  Serial.printf("Listing directory: %s\r\n", dirname);




  File root = fs.open(dirname);

  if (!root) {

    Serial.println("- failed to open directory");

    return;

  }

  if (!root.isDirectory()) {

    Serial.println(" - not a directory");

    return;

  }




  File file = root.openNextFile();

  while (file) {

    if (file.isDirectory()) {

      Serial.print("  DIR : ");

      Serial.println(file.name());

      if (levels) {

        listDir(fs, file.path(), levels - 1);

      }

    } else {

      Serial.print("  FILE: ");

      Serial.print(file.name());

      Serial.print("\tSIZE: ");

      Serial.println(file.size());

    }

    file = root.openNextFile();

  }

}




void createDir(fs::FS &fs, const char *path) {

  Serial.printf("Creating Dir: %s\n", path);

  if (fs.mkdir(path)) {

    Serial.println("Dir created");

  } else {

    Serial.println("mkdir failed");

  }

}




void removeDir(fs::FS &fs, const char *path) {

  Serial.printf("Removing Dir: %s\n", path);

  if (fs.rmdir(path)) {

    Serial.println("Dir removed");

  } else {

    Serial.println("rmdir failed");

  }

}




void readFile(fs::FS &fs, const char *path) {

  Serial.printf("Reading file: %s\r\n", path);




  File file = fs.open(path);

  if (!file || file.isDirectory()) {

    Serial.println("- failed to open file for reading");

    return;

  }




  Serial.println("- read from file:");

  while (file.available()) {

    Serial.write(file.read());

  }

  file.close();

}




void writeFile(fs::FS &fs, const char *path, const char *message) {

  Serial.printf("Writing file: %s\r\n", path);




  File file = fs.open(path, FILE_WRITE);

  if (!file) {

    Serial.println("- failed to open file for writing");

    return;

  }

  if (file.print(message)) {

    Serial.println("- file written");

  } else {

    Serial.println("- write failed");

  }

  file.close();

}




void appendFile(fs::FS &fs, const char *path, const char *message) {

  Serial.printf("Appending to file: %s\r\n", path);




  File file = fs.open(path, FILE_APPEND);

  if (!file) {

    Serial.println("- failed to open file for appending");

    return;

  }

  if (file.print(message)) {

    Serial.println("- message appended");

  } else {

    Serial.println("- append failed");

  }

  file.close();

}




void renameFile(fs::FS &fs, const char *path1, const char *path2) {

  Serial.printf("Renaming file %s to %s\r\n", path1, path2);

  if (fs.rename(path1, path2)) {

    Serial.println("- file renamed");

  } else {

    Serial.println("- rename failed");

  }

}




void deleteFile(fs::FS &fs, const char *path) {

  Serial.printf("Deleting file: %s\r\n", path);

  if (fs.remove(path)) {

    Serial.println("- file deleted");

  } else {

    Serial.println("- delete failed");

  }

}




// SPIFFS-like write and delete file, better use #define CONFIG_LITTLEFS_SPIFFS_COMPAT 1




void writeFile2(fs::FS &fs, const char *path, const char *message) {

  if (!fs.exists(path)) {

    if (strchr(path, '/')) {

      Serial.printf("Create missing folders of: %s\r\n", path);

      char *pathStr = strdup(path);

      if (pathStr) {

        char *ptr = strchr(pathStr, '/');

        while (ptr) {

          *ptr = 0;

          fs.mkdir(pathStr);

          *ptr = '/';

          ptr = strchr(ptr + 1, '/');

        }

      }

      free(pathStr);

    }

  }




  Serial.printf("Writing file to: %s\r\n", path);

  File file = fs.open(path, FILE_WRITE);

  if (!file) {

    Serial.println("- failed to open file for writing");

    return;

  }

  if (file.print(message)) {

    Serial.println("- file written");

  } else {

    Serial.println("- write failed");

  }

  file.close();

}




void deleteFile2(fs::FS &fs, const char *path) {

  Serial.printf("Deleting file and empty folders on path: %s\r\n", path);




  if (fs.remove(path)) {

    Serial.println("- file deleted");

  } else {

    Serial.println("- delete failed");

  }




  char *pathStr = strdup(path);

  if (pathStr) {

    char *ptr = strrchr(pathStr, '/');

    if (ptr) {

      Serial.printf("Removing all empty folders on path: %s\r\n", path);

    }

    while (ptr) {

      *ptr = 0;

      fs.rmdir(pathStr);

      ptr = strrchr(pathStr, '/');

    }

    free(pathStr);

  }

}




void testFileIO(fs::FS &fs, const char *path) {

  Serial.printf("Testing file I/O with %s\r\n", path);




  static uint8_t buf[512];

  size_t len = 0;

  File file = fs.open(path, FILE_WRITE);

  if (!file) {

    Serial.println("- failed to open file for writing");

    return;

  }




  size_t i;

  Serial.print("- writing");

  uint32_t start = millis();

  for (i = 0; i < 2048; i++) {

    if ((i & 0x001F) == 0x001F) {

      Serial.print(".");

    }

    file.write(buf, 512);

  }

  Serial.println("");

  uint32_t end = millis() - start;

  Serial.printf(" - %u bytes written in %" PRIu32 " ms\r\n", 2048 * 512, end);

  file.close();




  file = fs.open(path);

  start = millis();

  end = start;

  i = 0;

  if (file && !file.isDirectory()) {

    len = file.size();

    size_t flen = len;

    start = millis();

    Serial.print("- reading");

    while (len) {

      size_t toRead = len;

      if (toRead > 512) {

        toRead = 512;

      }

      file.read(buf, toRead);

      if ((i++ & 0x001F) == 0x001F) {

        Serial.print(".");

      }

      len -= toRead;

    }

    Serial.println("");

    end = millis() - start;

    Serial.printf("- %lu bytes read in %" PRIu32 " ms\r\n", (unsigned long)flen, end);

    file.close();

  } else {

    Serial.println("- failed to open file for reading");

  }

}




void setup() {

  Serial.begin(115200);




#ifdef TWOPART

  if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED, "/lfs2", 5, "part2")) {

    Serial.println("part2 Mount Failed");

    return;

  }

  appendFile(LittleFS, "/hello0.txt", "World0!\r\n");

  readFile(LittleFS, "/hello0.txt");

  LittleFS.end();




  Serial.println("Done with part2, work with the first lfs partition...");

#endif




  if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) {

    Serial.println("LittleFS Mount Failed");

    return;

  }

  Serial.println("SPIFFS-like write file to new path and delete it w/folders");

  writeFile2(LittleFS, "/new1/new2/new3/hello3.txt", "Hello3");

  listDir(LittleFS, "/", 3);

  deleteFile2(LittleFS, "/new1/new2/new3/hello3.txt");




  listDir(LittleFS, "/", 3);

  createDir(LittleFS, "/mydir");

  writeFile(LittleFS, "/mydir/hello2.txt", "Hello2");

  listDir(LittleFS, "/", 1);

  deleteFile(LittleFS, "/mydir/hello2.txt");

  removeDir(LittleFS, "/mydir");

  listDir(LittleFS, "/", 1);

  writeFile(LittleFS, "/hello.txt", "Hello ");

  appendFile(LittleFS, "/hello.txt", "World!\r\n");

  readFile(LittleFS, "/hello.txt");

  renameFile(LittleFS, "/hello.txt", "/foo.txt");

  readFile(LittleFS, "/foo.txt");

  deleteFile(LittleFS, "/foo.txt");

  testFileIO(LittleFS, "/test.txt");

  deleteFile(LittleFS, "/test.txt");




  Serial.println("Test complete");

}




void loop() {}


Which the Serial Monitor while running this code:

E (3) esp_littlefs: ./managed_components/joltwallet__littlefs/src/littlefs/lfs.c:1383:error: Corrupted dir pair at {0x0, 0x1}

E (3) esp_littlefs: mount failed,  (-84)
E (7) esp_littlefs: Failed to initialize LittleFS
LittleFS Mount Failed

ESP Dev Kit

Yes, no wiring needed.
I may be confused, but doesn't the LittleFS library expect some sort of 'file' in the sketch folder?

Maybe this?

I think this just uploads files needed to be on the ESP32, my files were directly being made in the code, in fact it used to worked, it just happened to be now that it always boots in the same error.

Try moving the partition. The bottom half of the IDE Tools menu contains the board-specific settings. Partition Scheme is one. LittleFS uses the same underlying partition type as SPIFFS; you might be using default 4MB with 1.5MB SPIFFS. Choose a different scheme like Minimal SPIFFS, which "only" has 190KB SPIFFS (the app size -- two of them to enable OTA updates -- is bigger).

See if the minimal LittleFS into sketch works. If that works, you can then try to switch back.

Otherwise, dig in on what looks like an error code: -84

I suppose you could also try cleaning the flash then uploading a small test file to the LittleFS using the IDE plugin described here: GitHub - earlephilhower/arduino-littlefs-upload: Build and uploads LittleFS filesystems for the Arduino-Pico RP2040, RP2350, ESP8266, and ESP32 cores under Arduino IDE 2.2.1 or higher · GitHub

Even if it also fails you may be lucky and get a more descriptive error message.

Also say which version of the ESP32 Arduino core that you are using.

As I already did based on the original post, I have tried almost every partition scheme to upload to.

looks like I couldn't find any answers.

I tried you're given method but it seems to not work for me and states the same error message.

Looks like fixing this could take a long time, so supposed buying a new ESP32 would get the job done or to just use a separate file system (e.g. sd)

You did mention it; I missed it.

The esp32 board has been using

The ^ allows minor and patch version updates. The latest is 1.22.1, where littlefs is actually a submodule, last updated in March: "update littlefs core to v2.11.3". Scrolling down to that line in the error message

Then scrolling up a few hundred lines, you can see the top of the function

For some light reading (while you await new hardware?) you can try to figure out how that code can go wrong.

You didn't answer this but if, as the post above by @kenb4 implies, there have been recent changes to the LittleFS code, then rolling back a few releases might help.
If, however, the flash is defective then it may also manifest itself in other ways so a replacement board would also seem a good idea.

Are you using a custom partition table and want to mount /lfs2 ?

LittleFS with Arduino uses the default SPIFFS partition and you don't have to specify its name,

LittleFS.begin (true);

will do. Under Tool | Partition scheme select one of SPIFFS partitions.

It you want custom partition table you have to write your own partitions.csv file.