aeron-io/aeron · error · ArchiveException

negative position encoded in the file name: " + filename

Error message

negative position encoded in the file name: " + filename

What it means

Thrown by Catalog when determining the last recorded position of a recording from its segment files: a segment file name encodes its starting position, and a parsed position that is negative is invalid. This indicates a malformed or corrupted segment file name in the archive directory, so the catalog cannot compute the recording's max position safely.

Solutions

  1. Inspect the archive directory and remove or rename the malformed segment file so only valid <recordingId>-<position>.rec files remain
  2. Run ArchiveTool verify on the archive directory to identify and fix inconsistent files
  3. Restore affected segment files from a clean backup with canonical names
  4. Check for backup/temp files (e.g. cp/mv artifacts) in the archive dir and move them out

Example fix

// before
mv archive/1000-4607182418800017413.rec archive/1000-rec.rec  // corrupts name-encoded position
// after
mv archive/1000-rec.rec archive/1000-4607182418800017413.rec  // restore canonical <recordingId>-<position>.rec
Defensive patterns

Strategy: try-catch

Validate before calling

import java.io.File;
import java.util.regex.Pattern;

private static final Pattern SEGMENT = Pattern.compile("^(\\d+)-(\\d+)(\\.rec)?$");

static boolean hasValidSegmentNames(File archiveDir, long recordingId) {
    File[] files = archiveDir.listFiles((d, n) -> n.startsWith(recordingId + "-"));
    if (files == null) return true;
    for (File f : files) {
        java.util.regex.Matcher m = SEGMENT.matcher(f.getName());
        if (!m.matches() || Long.parseLong(m.group(2)) < 0) return false;
    }
    return true;
}

Try / catch

try {
    aeronArchive.extendRecording(...);
} catch (ArchiveException e) {
    if (e.getMessage().startsWith("negative position encoded in the file name")) {
        // quarantine/remove the malformed segment file, run ArchiveTool verify, retry
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Scanning a recording's segment files (Catalog.scanLastFile / during replay/extend) where a file's name does not match the expected <recordingId>-<position>.rec pattern with a valid numeric position — parseSegmentFilePosition returns negative for unparseable or negative-encoded names.

Common situations: Manually renamed or partially written segment files; files created by a different/older Aeron version with a different naming scheme; stray files matching the glob (editor backups like 'foo.rec~', temp files) dropped into the archive directory; corrupted filenames after filesystem issues.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/Catalog.java:1178

                    }
                }
            }
        }

        return index;
    }

    static String findSegmentFileWithHighestPosition(final List<String> segmentFiles)
    {
        long maxSegmentPosition = NULL_POSITION;
        String maxFileName = null;

        for (final String filename : segmentFiles)
        {
            final long filePosition = parseSegmentFilePosition(filename);
            if (filePosition < 0)
            {
                throw new ArchiveException("negative position encoded in the file name: " + filename);
            }

            if (filePosition > maxSegmentPosition)
            {
                maxSegmentPosition = filePosition;
                maxFileName = filename;
            }
        }

        return maxFileName;
    }

    static long parseSegmentFilePosition(final String filename)
    {
        final int dashOffset = filename.indexOf('-');
        if (-1 == dashOffset)
        {
            throw new ArchiveException("invalid filename format: " + filename);

View on GitHub (pinned to 6d60124e15)