GoogleContainerTools/skaffold · error
creating file: %w
Error message
creating file: %w
What it means
VerifyOrCreateFile creates the config file with os.Create after ensuring parent directories exist; this error wraps a failure of that os.Create call. It fires when the parent directory exists but is not writable by the current user, or a rare race removes the directory between MkdirAll and Create. Called from ResolveConfigFile on first-run config bootstrap.
Source
Thrown at pkg/skaffold/util/util.go:133
o := t
return &o
}
func IsURL(s string) bool {
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}
// VerifyOrCreateFile checks if a file exists at the given path,
// and if not, creates all parent directories and creates the file.
func VerifyOrCreateFile(path string) error {
_, err := os.Stat(path)
if err != nil && os.IsNotExist(err) {
dir := filepath.Dir(path)
if err = os.MkdirAll(dir, 0744); err != nil {
return fmt.Errorf("creating parent directory: %w", err)
}
if _, err = os.Create(path); err != nil {
return fmt.Errorf("creating file: %w", err)
}
return nil
}
return err
}
// Expand replaces placeholders for a given key with a given value.
// It supports the ${key} and the $key syntax.
func Expand(text, key, value string) string {
text = strings.ReplaceAll(text, "${"+key+"}", value)
indices := regexp.MustCompile(`\$`+key).FindAllStringIndex(text, -1)
for i := len(indices) - 1; i >= 0; i-- {
from := indices[i][0]
to := indices[i][1]
if to >= len(text) || !isAlphaNum(text[to]) {View on GitHub (pinned to a1189de023)
Solutions
- Ensure the parent directory is writable: chmod u+w $(dirname <path>) or chown it to the running user.
- Point Skaffold at a writable config path (fix HOME or the config override flag/env).
- Remove any non-regular file occupying the path (ls -la <path>; special file/device node).
- Check disk quota/space and mount flags (rw vs ro) on the volume holding the config.
Example fix
# before: config dir owned by root $ ls -ld ~/.skaffold drwxr-xr-x 2 root root ~/.skaffold // after $ sudo chown -R $(id -u):$(id -g) ~/.skaffold
Defensive patterns
Strategy: validation
Validate before calling
func ensureWritableDir(dir string) error {
if err := os.MkdirAll(dir, 0o744); err != nil {
return err
}
probe, err := os.CreateTemp(dir, ".writable")
if err != nil {
return fmt.Errorf("%s not writable: %w", dir, err)
}
probe.Close(); os.Remove(probe.Name())
return nil
} Try / catch
if err := util.VerifyOrCreateFile(cfgPath); err != nil {
if strings.Contains(err.Error(), "creating file") && errors.Is(err, fs.ErrPermission) {
return fmt.Errorf("fix ownership of %s: %w", filepath.Dir(cfgPath), err)
}
return err
} Prevention
- chown config directories to the user running Skaffold (common in containers with root-owned HOME).
- Verify the target filesystem is mounted read-write and quota is not exhausted.
- In CI, set HOME to an ephemeral writable path (e.g. $RUNNER_TEMP).
- Check SELinux/AppArmor denials if permissions look correct but creation fails.
When it happens
Trigger: os.Stat reports the config path missing, parent directories were created (or already existed), but os.Create(path) fails — typically EACCES on the parent directory, or the path exists as a dangling entry/special file that cannot be opened for writing.
Common situations: Running as a non-root user in a container whose HOME is owned by root; a read-only bind mount for the config directory; SELinux/AppArmor denying writes to the config location; disk quota exceeded.
Related errors
- creating parent directory: %w
- writing %q to %q: %w
- reading config file: %w
- writing config file: %w
- retrieving home directory: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/8ababe94c5c83192.
Report an issue: GitHub.