{"id":"17ec3353208d0ef6","repo":"go-sql-driver/mysql","slug":"illegal-s-length-d","errorCode":null,"errorMessage":"illegal %s length %d","messagePattern":"illegal (.+?) length (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"utils.go","lineNumber":404,"sourceCode":"}\n\nfunc formatBinaryDateTime(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[:length], nil\n\t}\n\tvar dst []byte      // return value\n\tvar p1, p2, p3 byte // current digit pair\n\n\tswitch length {\n\tcase 10, 19, 21, 22, 23, 24, 25, 26:\n\tdefault:\n\t\tt := \"DATE\"\n\t\tif length > 10 {\n\t\t\tt += \"TIME\"\n\t\t}\n\t\treturn nil, fmt.Errorf(\"illegal %s length %d\", t, length)\n\t}\n\tswitch len(src) {\n\tcase 4, 7, 11:\n\tdefault:\n\t\tt := \"DATE\"\n\t\tif length > 10 {\n\t\t\tt += \"TIME\"\n\t\t}\n\t\treturn nil, fmt.Errorf(\"illegal %s packet length %d\", t, len(src))\n\t}\n\tdst = make([]byte, 0, length)\n\t// start with the date\n\tyear := binary.LittleEndian.Uint16(src[:2])\n\tpt := year / 100\n\tp1 = byte(year - 100*uint16(pt))\n\tp2, p3 = src[2], src[3]\n\tdst = append(dst,\n\t\tdigits10[pt], digits01[pt],","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/utils.go#L386-L422","documentation":"Thrown by formatBinaryDateTime (utils.go:404) when the DECLARED column length `length` is not in {10, 19, 21, 22, 23, 24, 25, 26} — the only legal text lengths for DATE (10) or DATETIME (19, or 19+fraction). The function builds the text representation of a binary DATE/DATETIME value and rejects lengths it cannot format. The interpolated type is 'DATE' or 'DATETIME'.","triggerScenarios":"Result scanning a DATE/DATETIME column from a binary-protocol row where the column metadata's declared length is unexpected — e.g. a malformed binary result set, or a server/column definition with a non-standard length. Fires from Scan on prepared-statement rows.","commonSituations":"Corrupted binary row packets (flaky network, buggy proxy); a non-MySQL server advertising odd column lengths; version skew between client expectations and server; buffer corruption. Rare under normal operation.","solutions":["Reproduce with the text protocol (plain db.Query without placeholders, or CAST(col AS CHAR)) to isolate binary-protocol corruption.","Bypass proxies/routers; connect directly to MySQL and confirm the column type/length with SHOW COLUMNS.","Check the server is a genuine MySQL/MariaDB and is on a supported version.","Report with the exact length value from the message if it reproduces against vanilla MySQL."],"exampleFix":"// before\nrows, _ := db.Query(\"SELECT d FROM t WHERE id=?\", id)\n\n// after: read as text for diagnosis\nvar s string\ndb.QueryRow(\"SELECT CAST(d AS CHAR) FROM t WHERE id=?\", id).Scan(&s)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := rows.Scan(...); err != nil {\n    if strings.Contains(err.Error(), \"illegal \") && strings.Contains(err.Error(), \"length\") {\n        // declared column length is unsupported; read via CAST AS CHAR\n    }\n}","preventionTips":["Verify DATE/DATETIME column definitions produce standard lengths with SHOW COLUMNS.","Connect directly to MySQL to bypass proxies that rewrite column metadata.","Keep the binary protocol path clean; report reproducible oddities upstream."],"tags":["datetime","binary-protocol","wire-format","prepared-statement"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}