GoogleContainerTools/skaffold · warning

unable to create log file for render step

Error message

unable to create log file for render step: %w

What it means

WithLogFile wraps the render output and creates a log file (render/<timestamp>-<filename>) when render is not muted. If logfile.Create fails (bad permissions, nonexistent log dir, disk full), the render cannot start and this error wraps the cause.

Solutions

  1. Check write permissions and free space for the skaffold log directory
  2. Remove any conflicting file/dir at the log path (e.g. a file named 'render')
  3. Run with --mute-render or set muted render to skip log-file creation
  4. Read the wrapped err for the exact OS-level failure (errno)

Example fix

// before: run in read-only container fs
// after
skaffold render --mute-render
# or grant write access to the log directory
Defensive patterns

Strategy: fallback

Validate before calling

logDir := filepath.Join(".skaffold", "logs")
if err := os.MkdirAll(logDir, 0o755); err != nil {
    return fmt.Errorf("cannot prepare log dir: %w", err)
}
if fi, err := os.Stat(logDir); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s is a file, not a directory", logDir)
}

Try / catch

closer, err := renderutil.WithLogFile(time.Now().Format(...)+".log", out, muted)
if err != nil {
    out, closer, err = out, func(){}, nil // proceed without a log file
}

Prevention

When it happens

Trigger: WithLogFile called while MuteRender() is false and logfile.Create('render', filename) fails due to filesystem errors creating the log file.

Common situations: Read-only filesystem or sandbox without write access to the log directory; disk quota exhausted; log dir path conflicts (file exists where a dir is needed).

Related errors


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

Appendix: source

Thrown at pkg/skaffold/render/util/logfile.go:42

	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/output"
)

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

type Muted interface {
	MuteRender() bool
}

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

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

	output.Default.Fprintln(out, "Starting render...")
	output.Default.Fprintln(out, "- writing log to", file.Name())

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

View on GitHub (pinned to a1189de023)