{"record":{"id":"3a26aefce97d39e9","repo":"AlexxIT/go2rtc","slug":"magic-unsupported-header","errorCode":null,"errorMessage":"magic: unsupported header: ","messagePattern":"magic: unsupported header: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/magic/producer.go","lineNumber":68,"sourceCode":"\t}\n\n\tswitch b[0] {\n\tcase mpegts.SyncByte:\n\t\treturn mpegts.Open(rd)\n\t}\n\n\t// support MJPEG with trash on start\n\t// https://github.com/AlexxIT/go2rtc/issues/747\n\tif b, err = rd.Peek(4096); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif i := bytes.Index(b, []byte{0xFF, 0xD8, 0xFF, 0xDB}); i > 0 {\n\t\t_, _ = io.ReadFull(rd, make([]byte, i))\n\t\treturn mjpeg.Open(rd)\n\t}\n\n\treturn nil, errors.New(\"magic: unsupported header: \" + hex.EncodeToString(b[:4]))\n}\n","sourceCodeStart":50,"sourceCodeEnd":70,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/magic/producer.go#L50-L70","documentation":"magic.Open is the format auto-detector: it peeks the first 4 bytes and dispatches to a known producer (Annex-B bitstream, WAV, Y4M, FLV, MJPEG, AAC, mpjpeg, MPEG-TS). If none of the magic signatures match — and no JPEG SOI/DB marker appears within the first 4096 bytes — it gives up and returns this error with the first 4 bytes hex-encoded, since it cannot determine which producer handles the input.","triggerScenarios":"Calling magic.Open on a reader whose first bytes are not one of the supported signatures: an MP4/MOV container, WebM/Matroska, raw PCM, ADTS with different framing, gzip-compressed stream, an HTTP body containing HTML error page, or a stream that starts with padding/garbage beyond the 4096-byte MJPEG recovery window.","commonSituations":"Using go2rtc source `magic:` with a URL that returns an error page instead of media; pointing at an MP4 file expecting live-stream detection; TLS endpoint returning binary handshake garbage; camera stream that is actually MPEG-PS or another proprietary format; network truncation yielding a short/garbled prefix.","solutions":["Check the hex value in the message against known signatures to identify the actual format (e.g. 66747970 = 'ftyp' means MP4), then use the appropriate producer or convert the stream first.","Verify the URL/endpoint actually serves the expected raw stream and not an HTML/JSON error page — curl the endpoint and inspect the first bytes.","Convert unsupported input with ffmpeg to a supported raw format, e.g. `ffmpeg -i input -c:v libx264 -f h264 -` for an Annex-B H.264 pipe.","If the stream is MJPEG with more than 4096 bytes of leading garbage, strip the leading bytes yourself before passing the reader to magic.Open."],"exampleFix":"// before\nresp, _ := http.Get(url)\np, err := magic.Open(resp.Body) // error: magic: unsupported header: 3c68746d (\"<htm\")\n\n// after: check content type / let ffmpeg transcode to a supported pipe\ncmd := exec.Command(\"ffmpeg\", \"-i\", url, \"-c\", \"copy\", \"-f\", \"h264\", \"-\")\nstdout, _ := cmd.StdoutPipe()\ncmd.Start()\np, err := magic.Open(stdout)","handlingStrategy":"try-catch","validationCode":"func sniffSupported(rd io.Reader) (bool, error) {\n\tb, err := bufio.NewReader(rd).Peek(4)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tsig := map[string]bool{\"\\x00\\x00\\x00\\x01\": true, \"RIFF\": true, \"YUV4\": true, \"FLV\\x01\": true, \"\\xFF\\xD8\": true, \"\\xFF\\xF1\": true, \"\\xFF\\xF9\": true, \"--\": true, \"\\x47\": true}\n\treturn sig[string(b[:1])] || sig[string(b[:2])] || sig[string(b[:3])] || sig[string(b)], nil\n}","typeGuard":null,"tryCatchPattern":"p, err := magic.Open(rd)\nif err != nil && strings.Contains(err.Error(), \"magic: unsupported header\") {\n\tlog.Warnf(\"unknown format, header=%s, falling back to ffmpeg transcode\", err.Error())\n\tp, err = openViaFFmpeg(source) // ffmpeg -i src -c copy -f mpegts -\n}","preventionTips":["Check the hex header in the error against known signatures to identify the true container","curl -v the source URL and inspect the first bytes to rule out HTML/JSON error pages","Prefer explicitly specifying the source format instead of relying on auto-detection for exotic streams","Keep leading-garbage workarounds within the 4096-byte MJPEG sniff window or strip padding yourself"],"tags":["format-detection","magic-bytes","streaming","unsupported-format"],"backgroundTag":"unsupported-enum-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"}