hashicorp/packer · error

Failed to open source file %s for reading: %s

Error message

Failed to open source file %s for reading: %s

What it means

The single-file compression path of Packer's compress post-processor could not open the artifact's source file for reading. os.Open failed, so no bytes were copied into the compressor and the build failed. This is a read-side file-access error, not a compression error.

Source

Thrown at post-processor/compress/post-processor.go:236

		ui.Say(fmt.Sprintf("Zipping %s", target))
		err = createZipArchive(artifact.Files(), output)
		if err != nil {
			return nil, false, false, fmt.Errorf("Error creating zip: %s", err)
		}
	default:
		// Filename indicates no tarball (just compress) so we'll do an io.Copy
		// into our compressor.
		if len(artifact.Files()) != 1 {
			return nil, false, false, fmt.Errorf(
				"Can only have 1 input file when not using tar/zip. Found %d "+
					"files: %v", len(artifact.Files()), artifact.Files())
		}
		archiveFile := artifact.Files()[0]
		ui.Say(fmt.Sprintf("Archiving %s with %s", archiveFile, compression))

		source, err := os.Open(archiveFile)
		if err != nil {
			return nil, false, false, fmt.Errorf(
				"Failed to open source file %s for reading: %s",
				archiveFile, err)
		}
		defer source.Close()

		if _, err = io.Copy(output, source); err != nil {
			return nil, false, false, fmt.Errorf("Failed to compress %s: %s",
				archiveFile, err)
		}
	}

	ui.Say(fmt.Sprintf("Archive %s completed", target))

	return newArtifact, false, false, nil
}

func (config *Config) detectFromFilename() {
	var result [][]string

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Verify the file listed in the error exists and is readable by the Packer process (ls -l / stat)
  2. Check permissions/ownership on the output directory and the artifact file
  3. Ensure no prior post-processor removes or moves artifact files before compress runs
  4. Re-run the build to rule out a transient filesystem issue

Example fix

# before (unreadable file)
chmod 600 output/disk.img
# after
chmod 644 output/disk.img
Defensive patterns

Strategy: validation

Validate before calling

// verify the single artifact file is openable before compression
if len(artifact.Files()) == 1 {
    f, err := os.Open(artifact.Files()[0])
    if err != nil { return fmt.Errorf("source unreadable: %w", err) }
    f.Close()
}

Try / catch

// Go: surface the OS-level cause from the wrapped error
if err != nil && strings.Contains(err.Error(), "Failed to open source file") {
    if errors.Is(err, os.ErrPermission) || strings.Contains(err.Error(), "permission denied") {
        // fix permissions and retry
    }
    return err
}

Prevention

When it happens

Trigger: The default (non tar/zip) branch calls os.Open(archiveFile) on the artifact's single file and the OS returns an error: file missing, permission denied, or path is a directory/symlink to nothing.

Common situations: A previous post-processor deleted or renamed the artifact file; artifact path became invalid after artifact.Files() was captured; running Packer as a user lacking read permission on the build output; file on a detached/unmounted volume.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/c6dc98ce5bb5c13b. Report an issue: GitHub.