gohugoio/hugo · error

failed to create resource spec

Error message

failed to create resource spec: %w

What it means

During Deps initialization (deps/deps.go:270) Hugo builds the resources.Spec via resources.NewSpec, which constructs the image processor (images.NewImageProcessor from the [imaging] config), the permalink expander (page.NewPermalinkExpander from [permalinks]), and caches. This wraps any of those failures, most commonly a bad imaging config.

Solutions

  1. Inspect the wrapped %w error to see whether imaging or permalinks failed.
  2. Validate [imaging]: quality 1-100, a supported resamplingFilter, a valid anchor.
  3. Validate [permalinks]: tokens match ':field' form and field names are valid.
  4. If embedding Hugo, ensure PathSpec, FileCaches, logger, MemCache and BuildState are populated before calling Deps.Init.

Example fix

# before
[imaging]
quality = 150          # out of range -> resource spec fails
resampleFilter = "foo"  # unknown filter

# after
[imaging]
quality = 75
resampleFilter = "box"
Defensive patterns

Strategy: validation

Validate before calling

// Validate the config slices that feed resources.NewSpec.
func ValidateResourceSpecConfig(imagingCfg images.Config, permalinks map[string]string) error {
    // imaging: sanity-check quality/filter/anchor per Hugo docs.
    if imagingCfg.Quality < 1 || imagingCfg.Quality > 100 {
        return fmt.Errorf("imaging.quality must be 1-100")
    }
    for kind, pattern := range permalinks {
        if strings.ContainsAny(pattern, " ") {
            return fmt.Errorf("permalinks.%s: invalid pattern %q", kind, pattern)
        }
    }
    return nil
}

Try / catch

if err := d.Init(); err != nil { // calls resources.NewSpec internally
    return fmt.Errorf("init deps: %w", err)
}

Prevention

When it happens

Trigger: Invalid [imaging] config (bad quality, unsupported filter, unknown anchor, misconfigured resize options); invalid [permalinks] entries that page.NewPermalinkExpander cannot compile; nil/missing cache or logger wiring in a programmatic embed.

Common situations: Setting [imaging] quality out of range, an unsupported resampling filter name, or a bad anchor after a Hugo upgrade; a malformed permalink token; embedding Hugo programmatically with incomplete Deps.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/833da15ceafa596b. Report an issue: GitHub.

Appendix: source

Thrown at deps/deps.go:272

	}

	if d.SourceSpec == nil {
		d.SourceSpec = source.NewSourceSpec(d.PathSpec, nil, d.Fs.Source)
	}

	var common *resources.SpecCommon
	if d.ResourceSpec != nil {
		common = d.ResourceSpec.SpecCommon
	}

	d.Cfg.BaseConfig()

	fileCaches := d.Cfg.FileCaches().(filecache.Caches)
	fileCaches.SetResourceFs(d.BaseFs.ResourcesCache)

	resourceSpec, err := resources.NewSpec(d.PathSpec, common, d.WasmDispatchers, fileCaches, d.MemCache, d.BuildState, d.Log, d, d.ExecHelper, d.BuildClosers, d.BuildState)
	if err != nil {
		return fmt.Errorf("failed to create resource spec: %w", err)
	}
	d.ResourceSpec = resourceSpec

	return nil
}

// TODO(bep) rework this to get it in line with how we manage templates.
func (d *Deps) Compile(prototype *Deps) error {
	var err error
	if prototype == nil {

		if err = d.TranslationProvider.NewResource(d); err != nil {
			return err
		}
		return nil
	}

	if err = d.TranslationProvider.CloneResource(d, prototype); err != nil {

View on GitHub (pinned to 52c9bd7908)