{"record":{"id":"f558e77f8fce7b43","repo":"go-sql-driver/mysql","slug":"invalid-time-packet-length-d","errorCode":null,"errorMessage":"invalid TIME packet length %d","messagePattern":"invalid TIME packet length (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"utils.go","lineNumber":465,"sourceCode":"func formatBinaryTime(src []byte, length uint8) (driver.Value, error) {\n\t// length expects the deterministic length of the zero value,\n\t// negative time and 100+ hours are automatically added if needed\n\tif len(src) == 0 {\n\t\treturn zeroDateTime[11 : 11+length], nil\n\t}\n\tvar dst []byte // return value\n\n\tswitch length {\n\tcase\n\t\t8,                      // time (can be up to 10 when negative and 100+ hours)\n\t\t10, 11, 12, 13, 14, 15: // time with fractional seconds\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"illegal TIME length %d\", length)\n\t}\n\tswitch len(src) {\n\tcase 8, 12:\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid TIME packet length %d\", len(src))\n\t}\n\t// +2 to enable negative time and 100+ hours\n\tdst = make([]byte, 0, length+2)\n\tif src[0] == 1 {\n\t\tdst = append(dst, '-')\n\t}\n\tdays := binary.LittleEndian.Uint32(src[1:5])\n\thours := int64(days)*24 + int64(src[5])\n\n\tif hours >= 100 {\n\t\tdst = strconv.AppendInt(dst, hours, 10)\n\t} else {\n\t\tdst = append(dst, digits10[hours], digits01[hours])\n\t}\n\n\tmin, sec := src[6], src[7]\n\tdst = append(dst, ':',\n\t\tdigits10[min], digits01[min], ':',","sourceCodeStart":447,"sourceCodeEnd":483,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/03d76c7e07908e255ce62d126d07ede3f2365d86/utils.go#L447-L483","documentation":"Raised by formatBinaryTime (utils.go:465) for the actual PAYLOAD length. The MySQL binary protocol encodes a TIME value as exactly 8 bytes (no fractional) or 12 bytes (with fractional seconds). Any other slice length means the value is malformed or the packet read pointer is desynchronized, so the driver refuses to format it.","triggerScenarios":"Reading a TIME column via a prepared statement (parseTime=false) when the server returns a binary value whose length is not 8 or 12. Reached via formatBinaryTime at packets.go:1414 with src = data[pos:pos+num]. Indicates truncation, packet desync, or a non-conforming server.","commonSituations":"Result-set desync after an earlier malformed packet, a proxy mishandling TIME values, network corruption, or a server fork with non-standard TIME encoding.","solutions":["Verify server/proxy compatibility; upgrade or replace the offending component.","Cast the TIME column to CHAR in SQL, or scan it as raw []byte and parse manually.","Switch the query to the text protocol (non-prepared) for the affected statement.","Restart the connection to clear desync state."],"exampleFix":"-- avoid binary TIME decoding entirely\nSELECT CAST(duration AS CHAR) AS duration FROM t WHERE id = ?;\n\nvar s string\ndb.QueryRow(query, id).Scan(&s)","handlingStrategy":"try-catch","validationCode":"// Payload length is server-controlled; validate protocol compliance instead.\nfunc isStandardBinaryTimePacketLen(n int) bool {\n    switch n {\n    case 8, 12:\n        return true\n    }\n    return false\n}","typeGuard":"func isStandardBinaryTimePacketLen(n int) bool {\n    switch n {\n    case 8, 12:\n        return true\n    }\n    return false\n}","tryCatchPattern":"var s string\nif err := db.QueryRow(q, id).Scan(&s); err != nil {\n    if strings.Contains(err.Error(), \"invalid TIME packet length\") {\n        var raw []byte\n        _ = db.QueryRow(`SELECT CAST(dur AS CHAR) FROM t WHERE id=?`, id).Scan(&raw)\n        s = string(raw)\n    }\n}","preventionTips":["Read TIME columns as CAST(... AS CHAR) through non-conforming servers.","Restart the pool after packet errors to recover from desync.","Pin and test server/proxy versions for TIME handling."],"tags":["mysql","time","binary-protocol","prepared-statements","protocol-error","packet-desync"],"backgroundTag":null,"analyzedSha":"03d76c7e07908e255ce62d126d07ede3f2365d86","analyzedAt":"2026-08-07T10:39:17.340Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}