hyperledger/fabric · error

%s: %s

Error message

%s: %s

What it means

WriteFileToPackage opens localpath and writes it into a tar stream (packagepath). This error wraps os.Open failures: the local file could not be opened, and the message carries the path plus the underlying error. It is thrown early, before any tar writing starts.

Source

Thrown at core/chaincode/platforms/util/writer.go:111

	}

	if err := filepath.Walk(rootDirectory, walkFn); err != nil {
		logger.Infof("Error walking rootDirectory: %s", err)
		return err
	}

	if !success {
		return errors.Errorf("no source files found in '%s'", srcPath)
	}
	return nil
}

// WriteFileToPackage writes a file to a tar stream.
func WriteFileToPackage(localpath string, packagepath string, tw *tar.Writer) error {
	logger.Debug("Writing file to tarball:", packagepath)
	fd, err := os.Open(localpath)
	if err != nil {
		return fmt.Errorf("%s: %s", localpath, err)
	}
	defer fd.Close()

	fi, err := fd.Stat()
	if err != nil {
		return fmt.Errorf("%s: %s", localpath, err)
	}

	header, err := tar.FileInfoHeader(fi, localpath)
	if err != nil {
		return fmt.Errorf("failed calculating FileInfoHeader: %s", err)
	}

	// Take the variance out of the tar by using zero time and fixed uid/gid.
	var zeroTime time.Time
	header.AccessTime = zeroTime
	header.ModTime = zeroTime
	header.ChangeTime = zeroTime

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the file at localpath exists (ls -l) and fix the path passed to WriteFileToPackage / GetDeploymentPayload
  2. Check read permissions on the file and that the peer process user can access it (and every parent directory)
  3. If packaging a directory of sources, ensure the build step that produces the file ran before packaging

Example fix

// before
err := util.WriteFileToPackage(missingArtifact, pkgPath, tw)
// after
if _, statErr := os.Stat(artifactPath); statErr != nil {
    return fmt.Errorf("artifact %s not found, run build first: %w", artifactPath, statErr)
}
err := util.WriteFileToPackage(artifactPath, pkgPath, tw)
Defensive patterns

Strategy: validation

Validate before calling

func canPackage(localpath string) error {
    fi, err := os.Stat(localpath)
    if err != nil { return fmt.Errorf("cannot stat %s: %w", localpath, err) }
    if fi.IsDir() { return fmt.Errorf("%s is a directory", localpath) }
    f, err := os.Open(localpath)
    if err != nil { return fmt.Errorf("cannot open %s: %w", localpath, err) }
    f.Close()
    return nil
}

Type guard

func isReadableFile(path string) bool {
    fi, err := os.Stat(path)
    return err == nil && fi.Mode().IsRegular()
}

Try / catch

if err := util.WriteFileToPackage(localpath, pkgPath, tw); err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) {
        return fmt.Errorf("package input unusable: %s: %w", pe.Path, pe.Err)
    }
    return err
}

Prevention

When it happens

Trigger: os.Open(localpath) fails because the file does not exist, the path is a directory, or the process lacks read permission.

Common situations: Packaging a chaincode whose build artifacts are missing (e.g. the code package path was misconfigured), running the peer as a user without read access to source files, or a typo/relative-path mistake in the deployment payload path.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/2ec9a48703aacb30. Report an issue: GitHub.