{"record":{"id":"af9501eeb2a714e9","repo":"AlexxIT/go2rtc","slug":"flv-wrong-header","errorCode":null,"errorMessage":"flv: wrong header","messagePattern":"flv: wrong header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/flv/producer.go","lineNumber":260,"sourceCode":"\t\t\t\twaitVideo = false\n\t\t\t}\n\t\t\tif !bytes.Contains(pkt.Payload, []byte(\"audiocodecid\")) {\n\t\t\t\twaitAudio = false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *Producer) readHeader() error {\n\tb := make([]byte, 9)\n\tif _, err := io.ReadFull(c.rd, b); err != nil {\n\t\treturn err\n\t}\n\n\tif string(b[:3]) != Signature {\n\t\treturn errors.New(\"flv: wrong header\")\n\t}\n\n\t_ = b[4] // flags (skip because unsupported by Reolink cameras)\n\n\tif skip := binary.BigEndian.Uint32(b[5:]) - 9; skip > 0 {\n\t\tif _, err := io.ReadFull(c.rd, make([]byte, skip)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *Producer) readPacket() (*rtp.Packet, error) {\n\t// https://rtmp.veriskope.com/pdf/video_file_format_spec_v10.pdf\n\tb := make([]byte, 4+11)\n\tif _, err := io.ReadFull(c.rd, b); err != nil {\n\t\treturn nil, err","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/flv/producer.go#L242-L278","documentation":"readHeader reads the 9-byte FLV header from the incoming stream and requires the first 3 bytes to equal the FLV signature (\"FLV\"). This error means the remote endpoint did not return an FLV-formatted stream: the bytes at the start of the response are not the FLV magic signature, so the producer cannot parse the container.","triggerScenarios":"Calling the flv producer's Dial/probe path against a URL that serves something other than an FLV stream: an RTSP URL, an HTML error page, a JSON API response, or a camera endpoint with the wrong stream type/channel parameter. Also fires when a proxy or auth portal intercepts the request and returns non-FLV content.","commonSituations":"Pointing the producer at a camera's RTSP or snapshot URL instead of its HTTP-FLV endpoint; camera web UI returning a login/HTML page because the session expired; reverse proxy or CDN error page replacing the stream body; firmware update changing the stream path.","solutions":["Point the producer at a URL that actually serves an HTTP-FLV stream (verify with `curl -s <url> | head -c 3` — it must print FLV).","Check camera configuration: stream type, channel, and that the FLV/HTTP-FLV service is enabled on the device.","Confirm no auth portal or reverse proxy is intercepting the response (check for 3xx redirects or HTML bodies).","Probe the URL with the library's probe path and fall back to an alternative stream URL on failure."],"exampleFix":"// before: non-FLV endpoint\nproducer, err := flv.NewProducer(\"rtsp://camera/stream\")\n// after: real HTTP-FLV endpoint, probed first\nconst flvURL = \"http://camera/flv?channel=0&streamType=main\"\nif err := flv.Probe(flvURL); err != nil {\n    log.Fatalf(\"%s does not serve FLV: %v\", flvURL, err)\n}\nproducer, err := flv.NewProducer(flvURL)","handlingStrategy":"validation","validationCode":"// verify the endpoint serves FLV before constructing the producer\nresp, err := http.Get(url)\nif err != nil { return err }\nhead := make([]byte, 3)\nn, _ := io.ReadFull(resp.Body, head)\nresp.Body.Close()\nif string(head[:n]) != \"FLV\" {\n    return fmt.Errorf(\"%s is not an FLV stream\", url)\n}","typeGuard":"func isFLVStream(header []byte) bool { return len(header) >= 3 && string(header[:3]) == \"FLV\" }","tryCatchPattern":"if err := producer.Start(); err != nil {\n    if strings.Contains(err.Error(), \"flv: wrong header\") {\n        // fall back to an alternative stream URL\n        err = fallbackProducer.Start()\n    }\n    if err != nil { log.Fatal(err) }\n}","preventionTips":["Always probe the URL (first 3 bytes must be \"FLV\") before wiring it into the producer.","Use the camera's documented HTTP-FLV endpoint, never RTSP or snapshot URLs.","Check for auth redirects/proxies that replace stream bodies with HTML."],"tags":["flv","stream","protocol","camera"],"backgroundTag":"invalid-stream-header","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"}