gofiber/fiber · error

failed to create directory: %w

Error message

failed to create directory: %w

What it means

Returned by Response.Save (client/response.go:157) when os.MkdirAll fails while creating the parent directory tree for the target file (created with mode 0o750). Save auto-creates missing directories; if creation fails (permission denied, read-only filesystem, invalid path) the error is wrapped here.

Source

Thrown at client/response.go:157

// Save writes the response body to a file or io.Writer.
// If a string path is provided, it creates directories if needed, then writes to a file.
// If an io.Writer is provided, it writes directly to it.
// When streaming is enabled, the body is read directly from the stream.
func (r *Response) Save(v any) error {
	switch p := v.(type) {
	case string:
		file := filepath.Clean(p)
		dir := filepath.Dir(file)

		// Create directory if it doesn't exist
		if _, err := os.Stat(dir); err != nil {
			if !errors.Is(err, fs.ErrNotExist) {
				return fmt.Errorf("failed to check directory: %w", err)
			}

			if err = os.MkdirAll(dir, 0o750); err != nil {
				return fmt.Errorf("failed to create directory: %w", err)
			}
		}

		// Create and write to file
		outFile, err := os.Create(file)
		if err != nil {
			return fmt.Errorf("failed to create file: %w", err)
		}
		defer func() { _ = outFile.Close() }() //nolint:errcheck // not needed

		// Use BodyStream() which handles both streaming and non-streaming cases
		if _, err = io.Copy(outFile, r.BodyStream()); err != nil {
			return fmt.Errorf("failed to write response body to file: %w", err)
		}

		return nil

	case io.Writer:

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Grant the process write permission on the base directory or choose a writable location (e.g. an attached volume).
  2. Pre-create the directory tree with correct ownership before calling Save.
  3. Ensure no path component is an existing file.
  4. Free disk space if MkdirAll fails due to ENOSPC.

Example fix

// before — directory auto-create fails on read-only layer
err := resp.Save("/app/cache/resp.json")

// after — pre-create the dir on a writable volume with correct perms
if err := os.MkdirAll("/data/cache", 0o750); err != nil {
    return fmt.Errorf("cannot create cache dir: %w", err)
}
err := resp.Save("/data/cache/resp.json")
Defensive patterns

Strategy: validation

Validate before calling

// Pre-create the output directory so Save does not have to.
if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil {
    return fmt.Errorf("cannot create output dir: %w", err)
}

Try / catch

if err := resp.Save(path); err != nil {
    if strings.Contains(err.Error(), "failed to create directory") {
        // choose a writable fallback location and retry
        path = filepath.Join(os.TempDir(), filepath.Base(path))
        return resp.Save(path)
    }
    return err
}

Prevention

When it happens

Trigger: Calling resp.Save("/new/nested/path/file") where the parent directories do not exist and MkdirAll cannot create them — permission denied on an ancestor, a read-only filesystem, a path component that is a file rather than a directory, or a path that exceeds filesystem limits.

Common situations: App user lacks write permission on the base directory; running on a read-only root/container layer; a path that conflicts with an existing file (e.g. /tmp is a file); disk full; path too long.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/6c4cb38364f76b0b.json. Report an issue: GitHub.