expressjs/express · error · TypeError

unknown value for etag function: ' + val

Error message

unknown value for etag function: ' + val

What it means

compileETag (lib/utils.js:130-152) converts the app's 'etag' setting into a header-generation function. Only a function, true, false, 'weak', or 'strong' are valid; any other value reaches the switch default at line 148 and throws a TypeError. This fires when the setting is applied — i.e. at app.set('etag', val) time — not per request.

Source

Thrown at lib/utils.js:148

exports.compileETag = function(val) {
  var fn;

  if (typeof val === 'function') {
    return val;
  }

  switch (val) {
    case true:
    case 'weak':
      fn = exports.wetag;
      break;
    case false:
      break;
    case 'strong':
      fn = exports.etag;
      break;
    default:
      throw new TypeError('unknown value for etag function: ' + val);
  }

  return fn;
}

/**
 * Compile "query parser" value to function.
 *
 * @param  {String|Function} val
 * @return {Function}
 * @api private
 */

exports.compileQueryParser = function compileQueryParser(val) {
  var fn;

  if (typeof val === 'function') {
    return val;

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Use one of the supported values: app.set('etag', 'weak'), 'strong', true, false, or a custom function(body, encoding).
  2. When sourcing from env vars, convert explicitly: app.set('etag', process.env.ETAG === 'true').
  3. To disable ETags, prefer app.disable('etag').

Example fix

// before
app.set('etag', process.env.ETAG); // 'true' (string) is invalid
// after
app.set('etag', process.env.ETAG === 'strong' ? 'strong' : 'weak');
Defensive patterns

Strategy: validation

Validate before calling

const VALID_ETAG = new Set([true, false, 'strong', 'weak']);
if (!VALID_ETAG.has(etagSetting) && typeof etagSetting !== 'function') {
  throw new TypeError(`invalid 'etag' setting: ${JSON.stringify(etagSetting)}`);
}
app.set('etag', etagSetting);

Type guard

function isValidEtagSetting(val) {
  return val === true || val === false || val === 'strong' || val === 'weak' || typeof val === 'function';
}

Try / catch

try {
  app.set('etag', config.etag);
} catch (err) {
  if (/unknown value for etag function/.test(err.message)) {
    // config supplied an unsupported value — fail startup with a clear config error
  }
  throw err;
}

Prevention

When it happens

Trigger: app.set('etag', 'true') or any other string besides 'weak'/'strong' (string 'true'/'false' from env vars is the classic case); app.set('etag', 1); app.disable/enable are fine, but passing a misspelled mode like 'week' throws.

Common situations: Reading the value from process.env — environment variables are always strings, so ETAG=true becomes the invalid string 'true'; config files (YAML/JSON) delivering unexpected types; copying settings between Express apps with a serialization step that stringifies booleans.

Related errors


AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31). Data as JSON: /data/errors/28512775163eb580.json. Report an issue: GitHub ↗.