{"record":{"id":"1beb6571dd1a4094","repo":"ethereum/go-ethereum","slug":"malformed-utf-8-data","errorCode":null,"errorMessage":"Malformed UTF-8 data","messagePattern":"Malformed UTF-8 data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"internal/jsre/deps/web3.js","lineNumber":8015,"sourceCode":"\t    var Utf8 = C_enc.Utf8 = {\n\t        /**\n\t         * Converts a word array to a UTF-8 string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The UTF-8 string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            try {\n\t                return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n\t            } catch (e) {\n\t                throw new Error('Malformed UTF-8 data');\n\t            }\n\t        },\n\n\t        /**\n\t         * Converts a UTF-8 string to a word array.\n\t         *\n\t         * @param {string} utf8Str The UTF-8 string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n\t         */\n\t        parse: function (utf8Str) {\n\t            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));","sourceCodeStart":7997,"sourceCodeEnd":8033,"githubUrl":"https://github.com/ethereum/go-ethereum/blob/6bb0588ad8e7f922e4ad5580f51265a4097af08f/internal/jsre/deps/web3.js#L7997-L8033","documentation":"CryptoJS's Utf8 stringify first Latin1-decodes the WordArray bytes, then runs them through decodeURIComponent(escape(...)) to produce UTF-8 text. If the byte sequence is not valid UTF-8, decodeURIComponent throws and it is rethrown as 'Malformed UTF-8 data'. In web3 this surfaces when hex/bytes that are not valid UTF-8 are decoded as a UTF-8 string (e.g. web3.toAscii / hexToString on arbitrary binary).","triggerScenarios":"Calling string decoding on data whose bytes are not valid UTF-8: raw contract return bytes, a hex string with odd length decoded through the Latin1 path, or ciphertext/random bytes fed to Utf8.stringify. Any invalid multi-byte sequence (e.g. 0x80-0xBF leading byte or truncated 0xC3 sequence) throws.","commonSituations":"Using web3.toAscii/toUtf8 on ABI-encoded return data, event data fields, or tx input that contains binary (hashes, addresses) rather than text; packing bugs producing odd-length hex.","solutions":["Confirm the data is actually text; for binary use the raw hex/bytes instead of UTF-8 decoding.","For ABI string types use the proper solidity decoder (web3.toBigNumber/web3's ABI decode) rather than toAscii.","Sanitize hex first: pad odd-length strings and strip 0x consistently.","Catch the error and fall back to a hex representation for display."],"exampleFix":"// before\nvar s = web3.toUtf8(txInputHex); // throws on non-UTF-8 bytes\n\n// after\nvar s;\ntry { s = web3.toUtf8(txInputHex); }\ncatch (e) { s = txInputHex; } // keep hex form for binary data","handlingStrategy":"try-catch","validationCode":"function looksLikeUtf8(hex) {\n  var s = hex.replace(/^0x/, '');\n  if (s.length % 2 !== 0) return false;\n  // crude check: reject control-heavy byte soup\n  var bytes = s.match(/.{2}/g).map(function (b) { return parseInt(b, 16); });\n  return bytes.filter(function (b) { return b < 0x09 || (b > 0x0d && b < 0x20); }).length === 0;\n}","typeGuard":null,"tryCatchPattern":"function decodeMaybeUtf8(hex) {\n  try { return web3.toUtf8(hex); }\n  catch (e) {\n    if (e.message === 'Malformed UTF-8 data') return hex; // binary payload\n    throw e;\n  }\n}","preventionTips":["Know the field's ABI type before string-decoding.","Use ABI decoders for string/bytes return values, not raw toAscii.","Default to hex representation when data type is unknown."],"tags":["web3","utf-8","encoding","cryptojs"],"backgroundTag":null,"analyzedSha":"6bb0588ad8e7f922e4ad5580f51265a4097af08f","analyzedAt":"2026-08-15T10:06:53.996Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}