Right, so you’ve built a beautiful template, you’re sure you’ve put it in the right place, and Hugo is…rendering something else entirely. Or maybe nothing at all. Welcome to the most common head-scratcher in all of Hugo-land. Before you start questioning your sanity, let me introduce you to your new best friend: hugo --verbose.

This flag is Hugo’s internal monologue. It’s the debug log that spills the beans on every single decision it makes, and crucially for us, it narrates its entire journey through the template lookup order. It’s the difference between guessing why your layouts/_default/single.html isn’t firing and knowing that Hugo found a more specific layouts/posts/single.html first and called it a day.

Why –verbose is Your Debugging Swiss Army Knife

Running hugo server --verbose (or just hugo --verbose for a build) doesn’t just show you template lookups. It’s a firehose of information: it’ll log every file it processes, any data it fetches, and its internal reasoning. This can feel overwhelming, but you learn to skim for the gold. The key is to run it after you have a specific problem. You’re not reading this for fun; you’re on a search mission.

Look for lines that contain DEBUG: and, more specifically, Found layout:. These are the smoking guns. Hugo will tell you exactly which file it landed on for a given piece of content.

Let’s say you have a piece of content at content/posts/my-great-post.md. You’ve made a fancy new template at layouts/_default/single.html, but Hugo seems to be ignoring it. Here’s what you do:

hugo --verbose | grep "my-great-post"

This pipes the enormous verbose output into grep, filtering only for lines mentioning your post. You’ll likely see something brilliant and illuminating like:

DEBUG: 2023/10/26 09:15:42 /posts/my-great-post.md: assigning weight of 0 to it
DEBUG: 2023/10/26 09:15:42 /posts/my-great-post.md: found type posts
DEBUG: 2023/10/26 09:15:42 /posts/my-great-post.md: found layout: [posts/single.html _default/single.html]
DEBUG: 2023/10/26 09:15:42 /posts/my-great-post.md: chose template: posts/single.html

Aha! The culprit is right there. Hugo did exactly what we told it to do. It looked for templates in order of specificity, and it found posts/single.html before it even got to _default/single.html. The last line confirms it: it chose the more specific template. Your _default template isn’t broken; it’s just being politely ignored because a more suitable candidate showed up to the party. Mystery solved.

Interpreting the Output Like a Pro

The output is a direct peek into Hugo’s brain, but you need to know its language.

  • found type: posts: This means Hugo has categorized your content based on its directory (content/posts/) and determined its .Type is “posts”. This is the value it will use for the layouts/{.Type}/ lookup.
  • found layout: [list.html section.html]: This shows the order in which Hugo is checking for templates. It’s reading this list from right to left. It will use the first one it finds. So [posts/single.html _default/single.html] means “check for posts/single.html, and if it doesn’t exist, then check _default/single.html”.
  • chose template:: This is the final verdict. This is the template file that will actually be rendered.

The most common “oh, duh” moment this reveals is when you forget you have an empty or nearly empty index.html or single.html file in a section-specific directory (like layouts/posts/) that’s overriding your intended _default template. The verbose output will proudly announce it’s choosing that empty file, and you’ll realize you created it six months ago during an experiment and forgot to delete it.

A Note on the Firehose

Be warned: the verbose output is massive, especially for a large site. That’s why grepping for your specific page title or a path is essential. Trying to read it raw is a recipe for eye strain. Use it surgically. Run a limited build if you can (hugo --verbose --renderToMemory -n 10 might build only 10 pages, for instance) to get a more manageable log while you’re testing.

This tool removes the magic and replaces it with mechanics. Once you see Hugo’s step-by-step logic a few times, the whole template lookup system stops being a mysterious black box and starts feeling like a predictable, if sometimes quirky, set of rules. And when those rules produce something absurd, you’ll have the evidence right in front of you.