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
- Sanitize the filename — reject path separators and control characters, ensure it is not an existing directory.
- Write into a directory the process owns.
- 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
- Sanitize user-supplied filenames (reject separators and control chars).
- Write only into directories writable by the process UID.
- Ensure the target is not a directory before overwrite.
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
- failed to check directory
- failed to create directory
- failed to write response body to file
- failed to write response body to writer
- client cannot be nil
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 neededView on GitHub (pinned to a105acad6c)