{"record":{"id":"f28eda1d966d50f5","repo":"denoland/deno","slug":"err-invalid-char","errorCode":"ERR_INVALID_CHAR","errorMessage":"Invalid character in trailer content [\"${field}\"]","messagePattern":"Invalid character in trailer content \\[\"(.+?)\"\\]","errorType":"exception","errorClass":"NodeTypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_http_outgoing.ts","lineNumber":546,"sourceCode":"    value: function addTrailers(headers: any) {\n      this._trailer = \"\";\n      const keys = ObjectKeys(headers);\n      const isArray = ArrayIsArray(headers);\n      let field, value;\n      for (let i = 0, l = keys.length; i < l; i++) {\n        if (isArray) {\n          field = headers[keys[i]][0];\n          value = headers[keys[i]][1];\n        } else {\n          field = keys[i];\n          value = headers[field];\n        }\n        if (typeof field !== \"string\" || !field || !checkIsHttpToken(field)) {\n          throw new ERR_INVALID_HTTP_TOKEN(\"Trailer name\", field);\n        }\n        if (checkInvalidHeaderChar(value)) {\n          debug('Trailer \"%s\" contains invalid characters', field);\n          throw new ERR_INVALID_CHAR(\"trailer content\", field);\n        }\n        this._trailer += field + \": \" + value + \"\\r\\n\";\n      }\n    },\n    writable: true,\n    enumerable: true,\n    configurable: true,\n  },\n  end: {\n    __proto__: null,\n    value: function end(chunk: any, encoding: any, callback: any) {\n      if (typeof chunk === \"function\") {\n        callback = chunk;\n        chunk = null;\n        encoding = null;\n      } else if (typeof encoding === \"function\") {\n        callback = encoding;\n        encoding = null;","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/_http_outgoing.ts#L528-L564","documentation":"While assembling trailers, addTrailers runs checkInvalidHeaderChar on each value; a value containing characters illegal in a header field value (control characters such as \\r, \\n, \\t, other C0 controls) throws ERR_INVALID_CHAR for 'trailer content'. The check exists to prevent header/trailer injection through unsanitized values, since the trailer is serialized verbatim after the terminal chunk.","triggerScenarios":"addTrailers({ 'x-checksum': hash + '\\n' }) (newline-terminated data); values sourced from user input, logs, or external APIs containing control characters; binary buffers stringified with control bytes.","commonSituations":"Checksums or metadata computed by tools that append newlines (wc, openssl dg2 outputs); proxying upstream values into trailers without sanitization; injecting request data into trailer values creating a smuggling vector.","solutions":["Sanitize values: strip/encode control characters before passing to addTrailers","Trim newline-terminated command output used as trailer values","Encode arbitrary data (base64/hex) so only printable ASCII remains"],"exampleFix":"// before\nres.addTrailers({ 'x-checksum': execSync('sha256sum f | cut -d\" \" -f1') }); // has trailing \\n\n\n// after\nconst sum = execSync('sha256sum f | cut -d\" \" -f1').toString().trim();\nres.addTrailers({ 'x-checksum': sum });","handlingStrategy":"validation","validationCode":"function sanitizeTrailerValue(v) {\n  return String(v).replace(/[\\r\\n\\t\\x00-\\x1f\\x7f]/g, '');\n}\nres.addTrailers({ 'x-checksum': sanitizeTrailerValue(sum) });","typeGuard":"const isCleanTrailerValue = (v) => typeof v === 'string' && !/[\\r\\n\\t\\x00-\\x1f\\x7f]/.test(v);","tryCatchPattern":"try { res.addTrailers(t); } catch (e) { if (e.code === 'ERR_INVALID_CHAR') { /* strip control chars and retry once */ } else throw e; }","preventionTips":["Trim newline-terminated tool output before use","Encode binary/b64 for trailer values","Treat trailer values as untrusted output; sanitize like headers"],"tags":["http","trailers","sanitization","security","node-compat"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}