aeron-io/aeron · error · IOException

NodeStateFile does not exist and createNew=false

Error message

NodeStateFile does not exist and createNew=false

What it means

NodeStateFile's constructor opens (and optionally creates) the cluster's node-state file in the cluster directory. When the file does not exist and createNew=false, the constructor cannot proceed and throws an IOException, since the caller explicitly forbade creating a new state file.

Solutions

  1. Create the file by constructing NodeStateFile with createNew=true
  2. Verify the clusterDir actually points at the existing cluster directory containing node.state file
  3. Restore the missing node-state file from backup
  4. If writing tooling, check new File(clusterDir, NodeStateFile.FILENAME).exists() first

Example fix

// before
NodeStateFile f = new NodeStateFile(clusterDir, false);
// after
File file = new File(clusterDir, NodeStateFile.FILENAME);
NodeStateFile f = new NodeStateFile(clusterDir, !file.exists());
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(clusterDir, NodeStateFile.FILENAME); if (!f.exists()) { /* create with createNew=true or fix path */ }

Try / catch

try { f = new NodeStateFile(clusterDir, false); } catch (IOException e) { f = new NodeStateFile(clusterDir, true); }

Prevention

When it happens

Trigger: Constructing NodeStateFile(clusterDir, createNew=false) against a cluster directory that has never had a node-state file written — i.e. a fresh/empty cluster dir or one where the file was deleted.

Common situations: Pointing the cluster dir at the wrong path; running recovery/tools against a fresh directory expecting existing state; the node-state file being deleted by cleanup scripts or lost because it was never committed to a mounted volume.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/9b93eaf6f0a3eae4. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/NodeStateFile.java:110

     * @param fileSyncLevel whether the mapped byte buffer should be synchronised with the underlying filesystem on
     *                      change.
     * @throws IOException if there is an error creating the file or <code>createNew == false</code> and the file does
     * not already exist.
     */
    public NodeStateFile(final File clusterDir, final boolean createNew, final int fileSyncLevel) throws IOException
    {
        this.fileSyncLevel = fileSyncLevel;
        final UnsafeBuffer buffer;
        MappedByteBuffer mappedFile = null;

        try
        {
            final File nodeStateFile = new File(clusterDir, NodeStateFile.FILENAME);
            if (!nodeStateFile.exists())
            {
                if (!createNew)
                {
                    throw new IOException("NodeStateFile does not exist and createNew=false");
                }

                mappedFile = IoUtil.mapNewFile(nodeStateFile, MINIMUM_FILE_LENGTH);
                buffer = new UnsafeBuffer(mappedFile, 0, mappedFile.capacity());
                buffer.verifyAlignment();

                initialiseDecodersOnCreation(
                    buffer,
                    nodeStateHeaderDecoder,
                    messageHeaderDecoder,
                    candidateTermDecoder);

                candidateTermIdOffset = calculateAndVerifyCandidateTermIdOffset();
                buffer.putLongVolatile(candidateTermIdOffset, Aeron.NULL_VALUE);
            }
            else
            {
                mappedFile = IoUtil.mapExistingFile(nodeStateFile, "NodeState");

View on GitHub (pinned to 6d60124e15)