netbirdio/netbird · error
failed to create upload dir
Error message
failed to create upload dir
What it means
HTTP 500 from handlePutRequest when os.MkdirAll(dirPath, 0750) fails while creating the per-id upload directory under the base (STORE_DIR, default /var/lib/netbird). The directory must exist before the file is opened, so any filesystem-level failure at this step aborts the upload; the errno is logged as 'Failed to create upload dir'.
Source
Thrown at upload-server/server/local.go:129
cleanBase := filepath.Clean(l.dir) + string(filepath.Separator)
dirPath := filepath.Clean(filepath.Join(l.dir, uploadDir))
if !strings.HasPrefix(dirPath, cleanBase) {
http.Error(w, "invalid path", http.StatusBadRequest)
log.Warnf("Path traversal attempt blocked (dir): %s", dirPath)
return
}
filePath := filepath.Clean(filepath.Join(dirPath, uploadFile))
if !strings.HasPrefix(filePath, cleanBase) {
http.Error(w, "invalid path", http.StatusBadRequest)
log.Warnf("Path traversal attempt blocked (file): %s", filePath)
return
}
if err = os.MkdirAll(dirPath, 0750); err != nil {
http.Error(w, "failed to create upload dir", http.StatusInternalServerError)
log.Errorf("Failed to create upload dir: %v", err)
return
}
flags := os.O_WRONLY | os.O_CREATE | os.O_EXCL
f, err := os.OpenFile(filePath, flags, 0600)
if err != nil {
if os.IsExist(err) {
http.Error(w, "file already exists", http.StatusConflict)
return
}
http.Error(w, "failed to create file", http.StatusInternalServerError)
log.Errorf("Failed to create file %s: %v", filePath, err)
return
}
defer func() { _ = f.Close() }()
if _, err = f.Write(body); err != nil {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Pre-create the base dir owned by the service user: mkdir -p /var/lib/netbird && chown <svcuser> /var/lib/netbird, or point STORE_DIR at a writable absolute path
- If the container filesystem is read-only, mount a writable volume at STORE_DIR
- Verify no regular file occupies any prefix of the path and check df -h / df -i for space or inode exhaustion
Example fix
# before: read-only container fs, every PUT returns 500 'failed to create upload dir' docker run -e STORE_DIR=/var/lib/netbird nb/upload-server # after: writable state dir mounted and owned docker run -e STORE_DIR=/var/lib/netbird -v nbuploads:/var/lib/netbird nb/upload-server
Defensive patterns
Strategy: validation
Validate before calling
// fail fast at startup instead of 500 on every upload
info, err := os.Stat(storeDir)
if err != nil || !info.IsDir() {
log.Fatalf("STORE_DIR unusable: %v", err)
}
probe := filepath.Join(storeDir, ".writable-probe")
if f, err := os.OpenFile(probe, os.O_WRONLY|os.O_CREATE, 0600); err != nil {
log.Fatalf("STORE_DIR not writable: %v", err)
} else {
_ = f.Close()
_ = os.Remove(probe)
} Try / catch
A 500 'failed to create upload dir' is a server-side environment fault; surface it to the operator (it will not self-heal on retry) and stop the upload batch.
Prevention
- Pre-create STORE_DIR and chown it to the service user before launch
- Mount a writable volume at STORE_DIR in read-only-rootfs containers
- Add a writability probe to the health/readiness check
When it happens
Trigger: Server process runs as a user without write permission on the base dir (a root-owned /var/lib/netbird); STORE_DIR on a read-only volume; a component of STORE_DIR exists as a regular file; disk or inode exhaustion.
Common situations: Running the upload-server container without a writable state volume; deploying as a non-root systemd service without chowning the state dir; Kubernetes pods with readOnlyRootFilesystem and no writable emptyDir mounted at STORE_DIR.
Related errors
- failed to create file
- write private key file (%s): %w
- write public key file (%s): %w
- failed to write file
- failed to list profiles: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/455c9f78a8f0fbac.
Report an issue: GitHub.