floci-io/floci · critical · IllegalStateException

Persistent storage path '" + root.toAbsolutePath() + "' is n

Error message

Persistent storage path '" + root.toAbsolutePath() + "' is not writable, but non-memory storage is enabled (" + services + "). Fix the volume mount permissions (it may be read-only or root-owned), or point FLOCI_STORAGE_PERSISTENT_PATH at a writable directory.

What it means

Thrown by PersistentPathValidator.validateAtBoot at startup when a write probe under the persistent storage root (including the s3 subdirectory when S3 is persistent) fails with IOException or SecurityException while any non-memory storage mode is enabled. The message lists the affected services and modes, and tells you to fix volume permissions or relocate FLOCI_STORAGE_PERSISTENT_PATH. The emulator refuses to boot rather than silently losing persistence.

Source

Thrown at src/main/java/io/github/hectorvent/floci/core/storage/PersistentPathValidator.java:58

            return;
        }

        Path root = Path.of(config.storage().persistentPath());
        try {
            probeWritable(root);
            Path s3Root = root.resolve("s3");
            boolean s3Persistent = persistent.stream().anyMatch(d -> "s3".equals(d.storageKey()));
            if (s3Persistent && Files.isDirectory(s3Root)) {
                probeWritable(s3Root);
            }
        } catch (IOException | SecurityException e) {
            String services = persistent.stream()
                    .map(d -> d.storageKey() + "=" + d.storageMode())
                    .distinct()
                    .limit(8)
                    .reduce((a, b) -> a + ", " + b)
                    .orElse("");
            throw new IllegalStateException(
                    "Persistent storage path '" + root.toAbsolutePath()
                            + "' is not writable, but non-memory storage is enabled (" + services
                            + "). Fix the volume mount permissions (it may be read-only or root-owned),"
                            + " or point FLOCI_STORAGE_PERSISTENT_PATH at a writable directory.", e);
        }
    }

    static void probeWritable(Path dir) throws IOException {
        Files.createDirectories(dir);
        Path probe = Files.createTempFile(dir, ".floci-write-probe", null);
        try {
            Files.deleteIfExists(probe);
        } catch (IOException e) {
            // The write itself succeeded, so the path is writable; a failed cleanup
            // must not abort boot as a false "not writable".
            probe.toFile().deleteOnExit();
        }
    }

View on GitHub (pinned to 62ff490619)

Solutions

  1. Make the persistence directory writable by the emulator user: chown -R <uid>:<gid> <host-path> or chmod, then restart
  2. Or point FLOCI_STORAGE_PERSISTENT_PATH / floci.storage.persistent-path at a writable directory
  3. For Kubernetes, set the pod securityContext fsGroup / runAsUser to match the volume ownership
  4. If persistence is not needed, switch storage mode to memory

Example fix

# before
docker run -v /data/floci:/var/lib/floci my/floci  # /data/floci owned by root

# after
sudo chown -R 1000:1000 /data/floci
docker run -u 1000 -v /data/floci:/var/lib/floci my/floci
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight the persistence dir with the same probe floci uses
static void probeWritable(Path dir) throws IOException {
    Files.createDirectories(dir);
    Path probe = Files.createTempFile(dir, ".floci-write-probe", null);
    Files.deleteIfExists(probe);
}

Try / catch

try {
    app.run(args);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("not writable")) { fixVolumeOwnership(); } // then restart; no in-app workaround
}

Prevention

When it happens

Trigger: Running floci in Docker with the persistence directory on a read-only or root-owned volume mount while floci.storage.mode (or per-service modes) is persistent/hybrid/wal; probeWritable creates a temp file '.floci-write-probe' and fails.

Common situations: Docker volume owned by root while the container runs as a non-root user; read-only bind mounts; SELinux denying writes to the mount; NFS/EFS mounts with restrictive perms; Kubernetes hostPath volumes without fsGroup.

Related errors


AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14). Data as JSON: /api/errors/62167843b1d69af2. Report an issue: GitHub.