{"record":{"id":"3e41ae2df87970f6","repo":"TeamNewPipe/NewPipe","slug":"cluster-element-found-without-info-and-or-tracks-e","errorCode":null,"errorMessage":"Cluster element found without Info and/or Tracks element at position {}","messagePattern":"Cluster element found without Info and/or Tracks element at position (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/org/schabi/newpipe/streams/WebMReader.java","lineNumber":294,"sourceCode":"        Element elem;\n        while ((elem = untilElement(ref, ID_INFO, ID_TRACKS, ID_CLUSTER)) != null) {\n            if (elem.type == ID_CLUSTER) {\n                obj.currentCluster = elem;\n                break;\n            }\n            switch (elem.type) {\n                case ID_INFO:\n                    obj.info = readInfo(elem);\n                    break;\n                case ID_TRACKS:\n                    obj.tracks = readTracks(elem, trackLacingExpected);\n                    break;\n            }\n            ensure(elem);\n        }\n\n        if (metadataExpected && (obj.info == null || obj.tracks == null)) {\n            throw new RuntimeException(\n                    \"Cluster element found without Info and/or Tracks element at position \"\n                            + ref.offset);\n        }\n\n        return obj;\n    }\n\n    private WebMTrack[] readTracks(final Element ref, final int lacingExpected) throws IOException {\n        final ArrayList<WebMTrack> trackEntries = new ArrayList<>(2);\n        Element elemTrackEntry;\n\n        while ((elemTrackEntry = untilElement(ref, ID_TRACK_ENTRY)) != null) {\n            final WebMTrack entry = new WebMTrack();\n            boolean drop = false;\n            Element elem;\n            while ((elem = untilElement(elemTrackEntry)) != null) {\n                switch (elem.type) {\n                    case ID_TRACK_NUMBER:","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/TeamNewPipe/NewPipe/blob/9e8be091560a69f35d44bd252eb00bc7911c977b/app/src/main/java/org/schabi/newpipe/streams/WebMReader.java#L276-L312","documentation":"Thrown by WebMReader when parsing a Matroska/WebM Segment element: the parser encountered a Cluster (the media-data container) before it saw the required Info and/or Tracks metadata elements. In a well-formed WebM file the Info element (codec/duration/timecode-scale metadata) and Tracks element (stream descriptions) must precede the first Cluster. The reader only sets metadataExpected when it knows the segment is not a live stream, so this fires on structurally invalid or truncated files where the metadata section is missing or was cut off before the Cluster began.","triggerScenarios":"readSegment() is called with metadataExpected=true; the while-loop breaks on the first ID_CLUSTER element (line 278-281) before both obj.info and obj.tracks are populated; the post-loop check at line 293 finds one or both null and throws. This happens when the stream's Segment starts directly with a Cluster, or when Info/Tracks appear after the Cluster instead of before it.","commonSituations":"Downloading a truncated or partially-written WebM/Opus audio file (e.g. download interrupted mid-write); receiving a live DASH/HLS WebM adaptation that omits the head metadata when saved; a remuxing tool that reordered EBML elements incorrectly; corrupt media cache left over from a failed download.","solutions":["Validate the source file is complete and well-formed before feeding it to WebMReader (check download finished, file size matches expected Content-Length).","Re-download or re-extract the stream: the metadata section was missing or truncated, indicating the source file is damaged.","If reading a live stream or segment that legitimately omits metadata, construct the reader so metadataExpected is false (the overload that knows this is a continuation/live segment).","Catch the RuntimeException at the call site and surface a user-facing 'media file is corrupt' message rather than crashing."],"exampleFix":"// before — crashes on truncated downloads\nWebMReader reader = new WebMReader(stream);\nSegment segment = reader.parse();\n\n// after — guard against corrupt/truncated media\ntry {\n    WebMReader reader = new WebMReader(stream);\n    Segment segment = reader.parse();\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Cluster element found without\")) {\n        throw new IOException(\"Corrupt WebM file: missing Info/Tracks metadata\", e);\n    }\n    throw e;\n}","handlingStrategy":"validation","validationCode":"// Verify the WebM stream has Info and Tracks before the first Cluster\n// by doing a lightweight EBML pre-scan, or check file completeness:\nif (streamFile.length() < minExpectedSize) {\n    throw new IOException(\"WebM source too small / likely truncated: \" + streamFile.length());\n}","typeGuard":null,"tryCatchPattern":"try {\n    WebMReader reader = new WebMReader(stream);\n    Segment seg = reader.parse();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Cluster element found without\")) {\n        // treat as corrupt/incomplete source — re-download or skip\n        throw new IOException(\"Corrupt WebM: missing Info/Tracks metadata\", e);\n    }\n    throw e;\n}","preventionTips":["Always verify a download completed fully (Content-Length matched) before demuxing.","Validate WebM magic bytes (0x1A45DFA3) at the start of the file before parsing.","Do not attempt to demux partial/live segments as full WebM files."],"tags":["webm","matroska","media-demuxer","corrupt-file","streaming"],"backgroundTag":null,"analyzedSha":"9e8be091560a69f35d44bd252eb00bc7911c977b","analyzedAt":"2026-08-14T00:11:33.519Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}