expressjs/express · error · Error

No default engine was specified and no extension was provide

Error message

No default engine was specified and no extension was provided.

What it means

The View constructor (lib/view.js:60-62) needs to know which template engine to use. It derives this from the file extension of the view name, falling back to the app's 'view engine' setting. If the render name has no extension and no default engine was configured, Express cannot pick an engine and throws synchronously.

Source

Thrown at lib/view.js:61

 *   - `defaultEngine` the default template engine name
 *   - `engines` template engine require() cache
 *   - `root` root path for view lookup
 *
 * @param {string} name
 * @param {object} options
 * @public
 */

function View(name, options) {
  var opts = options || {};

  this.defaultEngine = opts.defaultEngine;
  this.ext = extname(name);
  this.name = name;
  this.root = opts.root;

  if (!this.ext && !this.defaultEngine) {
    throw new Error('No default engine was specified and no extension was provided.');
  }

  var fileName = name;

  if (!this.ext) {
    // get extension from default engine name
    this.ext = this.defaultEngine[0] !== '.'
      ? '.' + this.defaultEngine
      : this.defaultEngine;

    fileName += this.ext;
  }

  if (!opts.engines[this.ext]) {
    // load engine
    var mod = this.ext.slice(1)
    debug('require "%s"', mod)

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Set a default engine: app.set('view engine', 'pug') — note the space, not a hyphen.
  2. Or include the extension explicitly in every render call: res.render('index.pug').
  3. If using a mounted sub-app, set 'view engine' on the sub-app too (settings like this are consulted on the app doing the rendering).

Example fix

// before
app.set('view-engine', 'ejs'); // typo: sets an unrelated key
res.render('index');
// after
app.set('view engine', 'ejs');
res.render('index');
Defensive patterns

Strategy: validation

Validate before calling

if (!app.get('view engine') && !path.extname(viewName)) {
  throw new Error(`Cannot render '${viewName}': set app.set('view engine', ...) or include the file extension`);
}

Try / catch

try {
  res.render('index'); // no extension
} catch (err) {
  if (/No default engine was specified/.test(err.message)) {
    // configure app.set('view engine', 'pug') or render 'index.pug'
  }
  next(err);
}

Prevention

When it happens

Trigger: res.render('index') (no extension) without ever calling app.set('view engine', 'ejs'|'pug'|...); calling app.render() on a bare name with the 'view engine' setting unset or misspelled (e.g. app.set('view-engine', 'ejs') — wrong key, a very common typo).

Common situations: Tutorial code that installed the engine package but skipped the app.set('view engine', ...) line; the 'view-engine' hyphen typo (silently sets an unused setting); rendering from a mounted sub-app that doesn't inherit the parent's setting the way the developer expected; tests constructing the app without the shared configuration bootstrap.

Related errors


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