GoogleContainerTools/skaffold · error

unable to create log file for deploy step: %w

Error message

unable to create log file for deploy step: %w

What it means

When deploy output is muted, WithLogFile creates a dedicated log file for the deploy step via logfile.Create("deploy", filename) and redirects output there. This error wraps any failure creating that file — bad directory, permissions, or name.

Source

Thrown at pkg/skaffold/deploy/util/logfile.go:43

)

// TimeFormat is used to name log files generated by deploy step
const TimeFormat = "2006-01-02_15-04-05"

type Muted interface {
	MuteStatusCheck() bool
	MuteDeploy() bool
}

// WithLogFile returns a file to write the deploy output to, and a function to be executed after the deploy step is complete.
func WithLogFile(filename string, out io.Writer, muted Muted) (io.Writer, func(), error) {
	if !muted.MuteDeploy() {
		return out, func() {}, nil
	}

	file, err := logfile.Create("deploy", filename)
	if err != nil {
		return out, func() {}, fmt.Errorf("unable to create log file for deploy step: %w", err)
	}

	output.Default.Fprintln(out, "Starting deploy...")
	fmt.Fprintln(out, "- writing logs to", file.Name())

	// After the deploy finishes, close the log file.
	return file, func() {
		file.Close()
	}, err
}

// WithStatusCheckLogFile returns a file to write the status-check output to, and a function to be executed after the status-check step is complete.
func WithStatusCheckLogFile(filename string, out io.Writer, muted Muted) (io.Writer, func(), error) {
	if !muted.MuteStatusCheck() {
		return out, func() {}, nil
	}

	file, err := logfile.Create("status-check", filename)

View on GitHub (pinned to a1189de023)

Solutions

  1. Ensure the log directory exists and is writable: create it or fix the path in the log-file configuration
  2. Check filesystem permissions for the user running skaffold
  3. Free disk space if the volume is full
  4. Run without muted output (default) so no log file is created

Example fix

// before
SKAFFOLD_DEPLOY_LOG_FILE=/nonexistent/dir/deploy.log
// after
mkdir -p /var/log/skaffold
SKAFFOLD_DEPLOY_LOG_FILE=/var/log/skaffold/deploy.log
Defensive patterns

Strategy: try-catch

Validate before calling

dir := filepath.Dir(logPath)
if err := os.MkdirAll(dir, 0o755); err != nil {
    return fmt.Errorf("log dir not creatable: %w", err)
}
if err := os.WriteFile(filepath.Join(dir, ".probe"), nil, 0o644); err != nil {
    return fmt.Errorf("log dir not writable: %w", err)
}

Try / catch

file, err := logfile.Create("deploy", filename)
if err != nil {
    log.Warnf("deploy log file unavailable (%v); falling back to stdout", err)
    return out, func() {}, nil
}

Prevention

When it happens

Trigger: WithLogFile called while muted.MuteDeploy() is true and logfile.Create fails: the target directory doesn't exist, the process lacks write permission, disk is full, or the filename contains illegal characters.

Common situations: Running skaffold with muted deploy output in read-only CI workspaces; SKAFFOLD_DEFAULT_DEPLOY_LOG_FILE or derived cache path pointing to a non-existent directory; Docker/Kaniko container run as non-root without volume write access.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/0401f606acc34902. Report an issue: GitHub.