GoogleContainerTools/skaffold · error
writing real file %q: %w
Error message
writing real file %q: %w
What it means
This error wraps any failure that occurs while streaming a regular file's contents into a tar archive via io.Copy in addFileToTar. The copy runs through a cancelableWriter that aborts when the context is canceled, so the wrapped error is either an underlying read/write I/O failure or ctx.Err() (e.g. context canceled). Skaffold surfaces it while building tar-based artifacts (CreateTar, CreateMappedTar, CreateTarWithParents).
Source
Thrown at pkg/skaffold/util/tar.go:205
return err
}
if mode.IsRegular() {
f, err := os.Open(src)
if err != nil {
return err
}
defer f.Close()
if ctx.Err() != nil {
return ctx.Err()
}
// Wrap the tar.Writer in a cancelableWriter that checks the context
cw := &cancelableWriter{w: tw, ctx: ctx}
// Proceed with copying the file content using the cancelable writer
if _, err := io.Copy(cw, f); err != nil {
return fmt.Errorf("writing real file %q: %w", src, err)
}
}
return nil
}
// Code copied from https://github.com/moby/moby/blob/master/pkg/archive/archive_windows.go
func chmodTarEntry(perm os.FileMode) os.FileMode {
// perm &= 0755 // this 0-ed out tar flags (like link, regular file, directory marker etc.)
permPart := perm & os.ModePerm
noPermPart := perm &^ os.ModePerm
// Add the x bit: make everything +x from windows
permPart |= 0111
permPart &= 0755
return noPermPart | permPart
}
View on GitHub (pinned to a1189de023)
Solutions
- Re-run the command; a transient I/O hiccup or intentional Ctrl-C cancel is the most common cause.
- Verify the source file still exists, is readable, and is stable (not being rewritten) during archiving.
- Check free disk space on the volume receiving the tar output.
- If canceled programmatically, extend or remove the context deadline/timeout around the tar operation.
Example fix
// before
err := util.CreateTar(ctx, tmpdir, deps.Dependencies)
// after
if ctx.Err() != nil {
return fmt.Errorf("context already canceled, skipping tar: %w", ctx.Err())
}
if err := util.CreateTar(ctx, tmpdir, deps.Dependencies); err != nil {
log.Entry(ctx).Warnf("tar failed (%v); retrying once", err)
err = util.CreateTar(context.WithoutCancel(ctx), tmpdir, deps.Dependencies)
} Defensive patterns
Strategy: try-catch
Validate before calling
// before archiving
if _, err := os.Stat(src); err != nil {
return fmt.Errorf("source unreadable: %w", err)
}
if err := ctx.Err(); err != nil {
return err
} Try / catch
if err := util.CreateTar(ctx, tmp, deps); err != nil {
var ctxErr = context.Canceled
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
// user cancel / timeout: treat as expected
return err
}
// transient I/O: retry once
return util.CreateTar(context.WithoutCancel(ctx), tmp, deps)
} Prevention
- Ensure source files are not modified/deleted while the tar is being created (freeze rebuilds during archive).
- Check free disk space on the output volume before large archives.
- Wrap long tar operations with an adequate context timeout and handle Ctrl-C gracefully.
- Pre-open/stat every dependency file to fail fast on unreadable inputs.
When it happens
Trigger: Calling CreateTar/CreateMappedTar/CreateTarWithParents on a source file that shrinks or becomes unreadable mid-copy, a disk-full or I/O error on the tar writer's destination, or the passed context being canceled while io.Copy is streaming the file bytes.
Common situations: Files deleted or truncated by another process (or a rebuild) while the tar is being assembled; the user hits Ctrl-C so the context cancels partway through copying; out-of-space on the output volume; network filesystems dropping mid-read.
Related errors
- creating tar gz: %w
- writing string: %w
- writing string: %w
- writing buffer contents to file: %w
- cannot create temp file: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/e76096343db4d9bf.
Report an issue: GitHub.