{"record":{"id":"8e16fcd60163f934","repo":"AlexxIT/go2rtc","slug":"mpegts-wrong-adaptation-size","errorCode":null,"errorMessage":"mpegts: wrong adaptation size","messagePattern":"mpegts: wrong adaptation size","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/mpegts/demuxer.go","lineNumber":90,"sourceCode":"\tsb := d.readByte() // Sync byte\n\tif sb != SyncByte {\n\t\treturn 0, false, errors.New(\"mpegts: wrong sync byte\")\n\t}\n\n\t_ = d.readBit()        // Transport error indicator (TEI)\n\tpusi := d.readBit()    // Payload unit start indicator (PUSI)\n\t_ = d.readBit()        // Transport priority\n\tpid = d.readBits16(13) // PID\n\n\t_ = d.readBits(2) // Transport scrambling control (TSC)\n\taf := d.readBit() // Adaptation field\n\t_ = d.readBit()   // Payload\n\t_ = d.readBits(4) // Continuity counter\n\n\tif af != 0 {\n\t\tadSize := d.readByte() // Adaptation field length\n\t\tif adSize > PacketSize-6 {\n\t\t\treturn 0, false, errors.New(\"mpegts: wrong adaptation size\")\n\t\t}\n\t\td.skip(adSize)\n\t}\n\n\treturn pid, pusi != 0, nil\n}\n\nfunc (d *Demuxer) skip(i byte) {\n\td.pos += i\n}\n\nfunc (d *Demuxer) readBytes(i byte) []byte {\n\td.pos += i\n\treturn d.buf[d.pos-i : d.pos]\n}\n\nfunc (d *Demuxer) readPSIHeader() {\n\t// https://en.wikipedia.org/wiki/Program-specific_information#Table_Sections","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/mpegts/demuxer.go#L72-L108","documentation":"The MPEG-TS demuxer validates the adaptation field length byte in every transport packet header. The spec limits the adaptation field to the bytes remaining after the fixed 4-byte TS header plus the 1-byte length field; go2rtc enforces this as adSize <= PacketSize-6 (184). If the packet claims a longer adaptation field, the stream is corrupt or misaligned, so ReadPacket fails rather than skipping garbage.","triggerScenarios":"Reading a TS packet whose adaptation_field_length byte (byte 4 of the packet, when adaptation_field_flag is set) exceeds 184 bytes, via mpegts.Demuxer.ReadPacket.","commonSituations":"Corrupt or truncated .ts files, packet loss in multicast/IPTS streams, byte-offset misalignment when starting demux mid-stream (not starting at a 0x47 sync byte boundary), or malformed streams produced by buggy muxers.","solutions":["Re-sync the demuxer to a valid 0x47 sync byte before reading packets (seek/skip to the next sync byte and retry ReadPacket).","Verify the input source integrity: re-download or re-record the .ts file, or check network loss on multicast inputs.","Ensure you start demuxing at a packet boundary (offset 0 or multiple of 188/192 bytes), not mid-packet.","If the source is a known-buggy muxer, remux the stream with ffmpeg (`ffmpeg -i in.ts -c copy out.ts`) to normalize adaptation fields."],"exampleFix":"// before: blind loop reading packets\nfor {\n    _, _, err := demux.ReadPacket()\n    if err != nil { return err }\n}\n// after: resync on corruption\nfor {\n    if _, _, err := demux.ReadPacket(); err != nil {\n        if err := resyncToSyncByte(reader); err != nil { return err }\n        continue\n    }\n    ...\n}","handlingStrategy":"retry","validationCode":"// Peek for TS sync byte before demuxing\nbuf, _ := bufio.NewReader(r).Peek(188)\nif len(buf) > 0 && buf[0] != 0x47 {\n    // not aligned; resync to next 0x47 before ReadPacket\n}","typeGuard":null,"tryCatchPattern":"for {\n    pid, pusi, err := demux.ReadPacket()\n    if err != nil {\n        if strings.Contains(err.Error(), \"wrong adaptation size\") {\n            if resyncErr := resyncToSyncByte(r); resyncErr != nil { return resyncErr }\n            continue\n        }\n        return err\n    }\n}","preventionTips":["Always start demuxing at a 188/192-byte packet boundary","Validate sources: check .ts files play correctly in ffprobe before feeding to the demuxer","Monitor input streams for packet loss (multicast/IPTV)","Remux known-buggy sources with ffmpeg before processing"],"tags":["mpegts","demuxer","stream-corruption"],"backgroundTag":"invalid-argument-value","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}