AlexxIT/go2rtc · error

magic: unsupported header:

Error message

magic: unsupported header: 

What it means

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.

Solutions

  1. 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.
  2. 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.
  3. 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.
  4. 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.

Example fix

// before
resp, _ := http.Get(url)
p, err := magic.Open(resp.Body) // error: magic: unsupported header: 3c68746d ("<htm")

// after: check content type / let ffmpeg transcode to a supported pipe
cmd := exec.Command("ffmpeg", "-i", url, "-c", "copy", "-f", "h264", "-")
stdout, _ := cmd.StdoutPipe()
cmd.Start()
p, err := magic.Open(stdout)
Defensive patterns

Strategy: try-catch

Validate before calling

func sniffSupported(rd io.Reader) (bool, error) {
	b, err := bufio.NewReader(rd).Peek(4)
	if err != nil {
		return false, err
	}
	sig := 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}
	return sig[string(b[:1])] || sig[string(b[:2])] || sig[string(b[:3])] || sig[string(b)], nil
}

Try / catch

p, err := magic.Open(rd)
if err != nil && strings.Contains(err.Error(), "magic: unsupported header") {
	log.Warnf("unknown format, header=%s, falling back to ffmpeg transcode", err.Error())
	p, err = openViaFFmpeg(source) // ffmpeg -i src -c copy -f mpegts -
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/3a26aefce97d39e9. Report an issue: GitHub.

Appendix: source

Thrown at pkg/magic/producer.go:68

	}

	switch b[0] {
	case mpegts.SyncByte:
		return mpegts.Open(rd)
	}

	// support MJPEG with trash on start
	// https://github.com/AlexxIT/go2rtc/issues/747
	if b, err = rd.Peek(4096); err != nil {
		return nil, err
	}

	if i := bytes.Index(b, []byte{0xFF, 0xD8, 0xFF, 0xDB}); i > 0 {
		_, _ = io.ReadFull(rd, make([]byte, i))
		return mjpeg.Open(rd)
	}

	return nil, errors.New("magic: unsupported header: " + hex.EncodeToString(b[:4]))
}

View on GitHub (pinned to c245815e75)