{"record":{"id":"86250a91a80494fa","repo":"go-sql-driver/mysql","slug":"protocol-error-illegal-decimals-value-d","errorCode":null,"errorMessage":"protocol error, illegal decimals value %d","messagePattern":"protocol error, illegal decimals value (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packets.go","lineNumber":1409,"sourceCode":"\t\t\tfieldTypeTimestamp, fieldTypeDateTime: // Timestamp YYYY-MM-DD HH:MM:SS[.fractal]\n\n\t\t\tnum, isNull, n := readLengthEncodedInteger(data[pos:])\n\t\t\tpos += n\n\n\t\t\tswitch {\n\t\t\tcase isNull:\n\t\t\t\tdest[i] = nil\n\t\t\t\tcontinue\n\t\t\tcase rows.rs.columns[i].fieldType == fieldTypeTime:\n\t\t\t\t// database/sql does not support an equivalent to TIME, return a string\n\t\t\t\tvar dstlen uint8\n\t\t\t\tswitch decimals := rows.rs.columns[i].decimals; decimals {\n\t\t\t\tcase 0x00, 0x1f:\n\t\t\t\t\tdstlen = 8\n\t\t\t\tcase 1, 2, 3, 4, 5, 6:\n\t\t\t\t\tdstlen = 8 + 1 + decimals\n\t\t\t\tdefault:\n\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t\"protocol error, illegal decimals value %d\",\n\t\t\t\t\t\trows.rs.columns[i].decimals,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tdest[i], err = formatBinaryTime(data[pos:pos+int(num)], dstlen)\n\t\t\tcase rows.mc.parseTime:\n\t\t\t\tdest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)\n\t\t\tdefault:\n\t\t\t\tvar dstlen uint8\n\t\t\t\tif rows.rs.columns[i].fieldType == fieldTypeDate {\n\t\t\t\t\tdstlen = 10\n\t\t\t\t} else {\n\t\t\t\t\tswitch decimals := rows.rs.columns[i].decimals; decimals {\n\t\t\t\t\tcase 0x00, 0x1f:\n\t\t\t\t\t\tdstlen = 19\n\t\t\t\t\tcase 1, 2, 3, 4, 5, 6:\n\t\t\t\t\t\tdstlen = 19 + 1 + decimals\n\t\t\t\t\tdefault:","sourceCodeStart":1391,"sourceCodeEnd":1427,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/03d76c7e07908e255ce62d126d07ede3f2365d86/packets.go#L1391-L1427","documentation":"While decoding binary-protocol result rows, the column metadata's 'decimals' byte for TIME columns must be 0, 0x1f, or 1-6. A value outside that range (e.g. 7-30, or 31 other than 0x1f) means the packet is corrupt or non-conformant, so the driver aborts with this protocol error.","triggerScenarios":"A malformed/corrupted packet from the server or an intermediary; a buggy or non-MySQL-compatible proxy mangling the column metadata; transient memory/network corruption. Extremely rare with compliant servers.","commonSituations":"Flaky network, a non-conforming proxy or MySQL fork, or hardware corruption on the wire; intermittent and hard to reproduce.","solutions":["Retry the query once (transient corruption often does not recur).","If reproducible, verify the server/proxy is MySQL-protocol-conformant and update or replace it.","Check network/TLS/MTU health and packet integrity; capture a packet trace if it persists.","Report upstream with the decimals value if it reproduces against a compliant server."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// No caller-side validation possible; this is a wire-integrity check. Best mitigation:\n// use TLS and keep the server/proxy on supported, conformant versions.","typeGuard":"null","tryCatchPattern":"// Treat as transient/protocol failure; retry with backoff, then surface.\nif err := rows.Scan(...); err != nil && strings.Contains(err.Error(), \"illegal decimals\") {\n    // retry once; if it persists, investigate server/proxy/network\n}","preventionTips":["Use TLS to prevent tampering/corruption on the wire.","Keep the server and any proxy on MySQL-protocol-conformant versions.","Implement a bounded retry for transient protocol errors."],"tags":["go","mysql","protocol","binary-protocol","corruption"],"backgroundTag":null,"analyzedSha":"03d76c7e07908e255ce62d126d07ede3f2365d86","analyzedAt":"2026-08-07T10:39:17.340Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}