Skip to content

MatroskaExtractor crashes with NPE on nested ChapterAtom elements (regression in 1.11.0) #3438

Closed

Description

@PaulWoitaschek

Version

Media3 1.11.1

More version details

Also reproduces on 1.11.0. Works on 1.10.1 (before Matroska chapter parsing was added to MatroskaExtractor).

Devices that reproduce the issue

  • Robolectric (SDK 35) unit tests on JVM
  • Not device-specific: the crash is in pure extractor parsing logic

Devices that do not reproduce the issue

None known on 1.11.x.

Reproducible in the demo app?

Not tested

Reproduction steps

  1. Take a Matroska file whose chapters are nested, i.e. a ChapterAtom contains child ChapterAtoms. This is allowed by the spec: ChapterAtom is recursive (\Segment\Chapters\EditionEntry\+ChapterAtom, RFC 9559).
  2. Extract it with MatroskaExtractor, e.g. via MetadataRetriever.retrieveTrackGroups() / retrieveDurationUs() or by playing it.

The file below was muxed with mkvmerge from this chapter XML using this script. mkvinfo (v102) parses it without warnings, and ffprobe reads its chapters without problems.

Structure:

EditionEntry
  ChapterAtom "Introduction"
    ChapterAtom "Getting Started"
    ChapterAtom "Basic Concepts"
  ChapterAtom "Main Content"
    ChapterAtom "Advanced Techniques"
    ChapterAtom "Practical Examples"
  ChapterAtom "Conclusion"

Expected result

The file is extracted successfully: tracks and duration are reported and chapters are exposed (at least the top-level ones, ideally the nested ones too).

Actual result

MatroskaExtractor throws an NPE before any track is output:

java.lang.NullPointerException
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:902)
    at androidx.media3.extractor.mkv.MatroskaExtractor.endMasterElement(MatroskaExtractor.java:978)
    at androidx.media3.extractor.mkv.MatroskaExtractor$InnerEbmlProcessor.endMasterElement(MatroskaExtractor.java:2356)
    at androidx.media3.extractor.mkv.DefaultEbmlReader.read(DefaultEbmlReader.java:88)
    at androidx.media3.extractor.mkv.MatroskaExtractor.read(MatroskaExtractor.java:659)

Claude Analysis:

Cause: the extractor tracks a single currentChapter field instead of a stack. startMasterElement(ID_CHAPTER_ATOM) overwrites it with the nested atom, the nested atom's endMasterElement sets it to null, and the parent atom's endMasterElement then hits checkNotNull(currentChapter). A ChapterDisplay/ChapterTimeStart etc. following a nested atom inside the parent would similarly fail in getCurrentChapter().

Because the error is thrown while parsing, the whole file becomes unusable: MetadataRetriever fails for both track groups and duration, and the file can't be played, even though it is valid and worked in 1.10.1.

A side note on the symptom: under Robolectric, the MetadataRetriever future never completes (instead of failing), because MetadataRetrieverInternal only surfaces the prepare error through a sendEmptyMessageDelayed poll, and the paused looper's clock doesn't advance while the test thread is blocked waiting on the future.

Context: this blocks the Voice audiobook player from moving to 1.11 and adopting the new chapters API: PaulWoitaschek/Voice#3779

You can find the exact reproducer also here: PaulWoitaschek/Voice#3703

Media

https://github.com/PaulWoitaschek/Voice/raw/f827b30dc6d8db88d206332b70331dd31e38563c/core/scanner/src/test/resources/mka_nested_chapters.mka (~1 MB, silent AAC audio with nested chapters)

Activity

  1. self-assigned this
    on Oct 2, 2026
  2. sandreas commented on Oct 5, 2026

    @sandreas

    @icbaker
    Reproduced the issue on my system. This is a nasty bug.

  3. icbaker commented on Oct 5, 2026

    @icbaker
    Collaborator

    This is fixed by the commit linked above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions