GoogleContainerTools/skaffold · error
error opening file: %w
Error message
error opening file: %w
What it means
UploadFile wraps os.Open failures for the local source file before uploading it to GCS. It means the src path could not be opened for reading: it does not exist, is a directory, or the process lacks read permission. The OS error is wrapped with %w so errors.Is/As still work.
Source
Thrown at pkg/skaffold/gcs/client/native.go:102
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("failed to create directory: %v", err)
}
}
if err := bucket.DownloadObject(ctx, fullPath, uri); err != nil {
return err
}
}
return nil
}
// Uploads a single file to the given dst.
func (n *Native) UploadFile(ctx context.Context, src, dst string) error {
f, err := os.Open(src)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
}
defer f.Close()
urinfo, err := n.parseGCSURI(dst)
if err != nil {
return err
}
bucket, err := GetBucketManager(ctx, urinfo.Bucket)
if err != nil {
return err
}
isDirectory, err := n.isGCSDirectory(ctx, bucket, urinfo)
if err != nil {
return err
}
View on GitHub (pinned to a1189de023)
Solutions
- Verify the src path exists and is a regular file (os.Stat) before calling UploadFile; the wrapped error usually says 'no such file or directory'
- Fix the path (use an absolute path or ensure the expected working directory)
- Grant the process read permission on the file (chmod/chown or run as the owning user)
- Check that the build/generation step that produces the file ran before the upload
Example fix
// before
n.UploadFile(ctx, "./out/app.tar.gz", "gs://bucket/artifacts/") // file not built yet
// after
if _, err := os.Stat("./out/app.tar.gz"); err != nil {
return fmt.Errorf("artifact missing, run build first: %w", err)
}
if err := n.UploadFile(ctx, "./out/app.tar.gz", "gs://bucket/artifacts/"); err != nil { /* handle */ } Defensive patterns
Strategy: validation
Validate before calling
func ensureReadableFile(path string) error {
fi, err := os.Stat(path)
if err != nil {
return fmt.Errorf("source missing: %w", err)
}
if fi.IsDir() {
return fmt.Errorf("%s is a directory, need a file", path)
}
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("%s not readable: %w", path, err)
}
return f.Close()
}
// call ensureReadableFile(src) before UploadFile Prevention
- Stat the source file before every upload
- Ensure the producing build step completes before the upload step
- Use absolute paths or set and verify the working directory
- Check file permissions in containerized environments
When it happens
Trigger: Calling Native.UploadFile(ctx, src, dst) where src is missing, is a directory, is a broken symlink, or is unreadable by the current user (e.g. src="./config.yaml" when the file was never created).
Common situations: Uploading a generated artifact before the build step produced it; typo in the source path; file deleted by a cleanup step; running with a different working directory than expected; container user lacks read permission on a mounted file.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- failed to create directory: %v
- failed to create file: %v
- failed creating Google Cloud Storage cache directory for %q:
- failed to create the tmp directory: %w
- failed to create the tmp directory: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/f8fb3207fa0a43e9.
Report an issue: GitHub.