gohugoio/hugo · error

failed to save file %q: %s

Error message

failed to save file %q: %s

What it means

Emitted in `convertJekyllPost` when `helpers.WriteToDisk` fails writing the converted post to the target Hugo content directory. Conversion succeeded; the failure is at the filesystem write step, so the error is almost always an OS-level I/O or permission problem rather than a content problem.

Source

Thrown at commands/import.go:337

		return err
	}
	pf, err := pageparser.ParseFrontMatterAndContent(bytes.NewReader(contentBytes))
	if err != nil {
		return fmt.Errorf("failed to parse file %q: %s", filename, err)
	}
	newmetadata, err := c.convertJekyllMetaData(pf.FrontMatter, postName, postDate, draft)
	if err != nil {
		return fmt.Errorf("failed to convert metadata for file %q: %s", filename, err)
	}

	content, err := c.convertJekyllContent(newmetadata, string(pf.Content))
	if err != nil {
		return fmt.Errorf("failed to convert content for file %q: %s", filename, err)
	}

	fs := hugofs.Os
	if err := helpers.WriteToDisk(targetFile, strings.NewReader(content), fs); err != nil {
		return fmt.Errorf("failed to save file %q: %s", filename, err)
	}
	return nil
}

func (c *importCommand) copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) {
	fs := hugofs.Os

	fi, err := fs.Stat(jekyllRoot)
	if err != nil {
		return err
	}
	if !fi.IsDir() {
		return errors.New(jekyllRoot + " is not a directory")
	}
	err = os.MkdirAll(dest, fi.Mode())
	if err != nil {
		return err
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Check write permissions on the target directory and its parents; run the import as a user that can write there.
  2. Verify free disk space and that the target path is on a writable filesystem.
  3. On Windows, rename source posts whose filenames contain characters invalid on the target filesystem, then re-run.
Defensive patterns

Strategy: validation

Validate before calling

// Verify target dir exists and is writable before import
if err := os.MkdirAll(targetDir, 0o755); err != nil {
    return fmt.Errorf("target not writable: %w", err)
}
if f, err := os.CreateTemp(targetDir, ".probe"); err != nil {
    return err
} else { f.Close(); os.Remove(f.Name()) }

Try / catch

if err := saveFile(dst, content); err != nil {
    if errors.Is(err, fs.ErrPermission) {
        // fix permissions / choose another target dir
    }
    return err
}

Prevention

When it happens

Trigger: `hugo import jekyll` writing the converted file to `<targetDir>/<relPath>` fails — e.g. the target directory is not writable, the disk is full, the path exceeds OS limits, or the filename contains characters invalid on the target filesystem (e.g. `:` on Windows).

Common situations: Importing into a read-only or root-owned directory, running on Windows with Jekyll filenames containing characters illegal in NTFS, network/overlay filesystems, or out-of-space containers.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/bc89f999b3faece9.json. Report an issue: GitHub ↗.