gofiber/fiber · error

failed to create file

Error message

failed to create file: %w

What it means

After ensuring the directory exists, Response.Save calls os.Create(file). This wraps a failure of that call: permission denied, the path names a directory, invalid characters, or read-only filesystem.

Solutions

  1. Sanitize the filename — reject path separators and control characters, ensure it is not an existing directory.
  2. Write into a directory the process owns.
  3. If overwriting, ensure the existing file is writable and not a directory.

Example fix

// before
if err := resp.Save(filepath.Join(dir, userInput)); err != nil { ... }

// after
if strings.ContainsAny(userInput, "/\") || userInput == "" {
    return errors.New("invalid filename")
}
if err := resp.Save(filepath.Join(dir, userInput)); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

if strings.ContainsAny(name, "/\") || name == "" {
    return errors.New("invalid filename")
}
if info, err := os.Stat(name); err == nil && info.IsDir() {
    return errors.New("save target is a directory")
}

Prevention

When it happens

Trigger: The final path component is a directory; the process lacks write permission on the directory; the filename contains illegal characters (NUL, slashes on Windows); the filesystem is read-only.

Common situations: Passing a directory path as the save target; write-protected mounts; user-supplied filenames with path separators; running as a UID without write rights.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/709010365c336a70. Report an issue: GitHub.

Appendix: source

Thrown at client/response.go:206

	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:
		// Use BodyStream() which handles both streaming and non-streaming cases
		if _, err := io.Copy(p, r.BodyStream()); err != nil {
			return fmt.Errorf("failed to write response body to writer: %w", err)
		}
		// Close the writer if it implements io.WriteCloser
		if pc, ok := p.(io.WriteCloser); ok {
			_ = pc.Close() //nolint:errcheck // not needed

View on GitHub (pinned to a105acad6c)