{"record":{"id":"0e78a03270e67989","repo":"denoland/deno","slug":"err-invalid-http-token-0e78a0","errorCode":"ERR_INVALID_HTTP_TOKEN","errorMessage":"Trailer name must be a valid HTTP token [\"${field}\"]","messagePattern":"Trailer name must be a valid HTTP token \\[\"(.+?)\"\\]","errorType":"exception","errorClass":"NodeTypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/_http_outgoing.ts","lineNumber":542,"sourceCode":"    configurable: true,\n  },\n  addTrailers: {\n    __proto__: null,\n    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;","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/_http_outgoing.ts#L524-L560","documentation":"OutgoingMessage#addTrailers iterates the supplied headers object (or [name, value] pairs) and requires every field name to be a non-empty string that passes checkIsHttpToken — the RFC 7230 token charset. Failing names (including non-strings such as numbers from object keys, empty strings, or names with separators/unicode) throw ERR_INVALID_HTTP_TOKEN for 'Trailer name'. The trailer string is assembled into this._trailer for the terminating chunk.","triggerScenarios":"res.addTrailers({ 'Content-MD5 ': hash }) (trailing space); addTrailers(obj) where obj keys came from JSON with numeric-looking names; header names containing spaces or non-ASCII from dynamic generation.","commonSituations":"Generating trailer names from data (checksums, counters) without validating the charset; porting header objects whose keys are coerced by JSON parsing; copy-paste typos with invisible whitespace.","solutions":["Use fixed, well-formed trailer names: 'content-md5', 'x-trace-id'","Validate dynamic names against /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ before addTrailers","If the name cannot be a token, put the value in the body or a header instead of a trailer"],"exampleFix":"// before\nres.addTrailers({ [metricName]: value }); // metricName = 'resp time'\n\n// after\nconst TOKEN_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\nconst name = TOKEN_RE.test(metricName) ? metricName : 'x-metric';\nres.addTrailers({ [name]: value });","handlingStrategy":"validation","validationCode":"const HTTP_TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\nfunction validTrailerNames(t) {\n  return Object.keys(t).every((k) => HTTP_TOKEN.test(k));\n}\nif (validTrailerNames(trailers)) res.addTrailers(trailers);","typeGuard":"const isTrailerTokenName = (n) => typeof n === 'string' && n.length > 0 && /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(n);","tryCatchPattern":"try { res.addTrailers(trailers); } catch (e) { if (e.code === 'ERR_INVALID_HTTP_TOKEN') { /* drop bad names or send plain headers */ } else throw e; }","preventionTips":["Use a fixed set of trailer names","Never derive trailer names from user data","Validate dynamic keys with the token regex before addTrailers"],"tags":["http","trailers","token","validation","node-compat"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}