hyperledger/fabric · error

failed to write header for %s: %s

Error message

failed to write header for %s: %s

What it means

After building the header, the function writes it to the tar.Writer via tw.WriteHeader. Failure here means the tar stream itself rejected the write — most commonly the underlying writer returned an error (closed/broken pipe, disk full) or the header is invalid for the stream format.

Source

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

	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
	header.Name = packagepath
	header.Mode = 0o100644
	header.Uid = 500
	header.Gid = 500
	header.Uname = ""
	header.Gname = ""

	err = tw.WriteHeader(header)
	if err != nil {
		return fmt.Errorf("failed to write header for %s: %s", localpath, err)
	}

	is := bufio.NewReader(fd)
	_, err = io.Copy(tw, is)
	if err != nil {
		return fmt.Errorf("failed to write %s as %s: %s", localpath, packagepath, err)
	}

	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the underlying writer/package destination for disk space or closed-handle errors reported in the wrapped %s
  2. Shorten the packaged file's relative path so the header name fits the tar format limits
  3. Create a fresh tar.Writer for each package; do not reuse one after a prior error

Example fix

// before
tarFileName := deeplyNestedFileAbsPath // >100 chars
util.WriteFileToPackage(deeplyNestedFileAbsPath, pkgPath, tw)
// after
relName, _ := filepath.Rel(pkgRoot, deeplyNestedFileAbsPath) // short relative name
tarFileName := relName
util.WriteFileToPackage(deeplyNestedFileAbsPath, pkgPath, tw)
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure header name fits USTAR limits before calling
rel, err := filepath.Rel(pkgRoot, localpath)
if err != nil || len(rel) > 100 { return fmt.Errorf("packaged name too long: %s", rel) }
// ensure destination writable
if err := checkWritable(pkgPath); err != nil { return err }

Type guard

func tarNameFits(path string, root string) bool {
    rel, err := filepath.Rel(root, path)
    return err == nil && len(rel) <= 100 && rel != ".."
}

Try / catch

if err := util.WriteFileToPackage(localpath, pkgPath, tw); err != nil {
    if strings.Contains(err.Error(), "failed to write header") {
        return fmt.Errorf("tar stream rejected header for %s; check output writer state and path length: %w", localpath, err)
    }
    return err
}

Prevention

When it happens

Trigger: tw.WriteHeader(header) returns an error: the tar.Writer previously hit an error and is closed for further writes, the underlying io.Writer (file/socket) failed, or the header name exceeds format limits (USTAR 100-char name without PAX support).

Common situations: Writing to an already-failed output stream (disk full on the package file), very long source paths exceeding USTAR name limits, or the tar.Writer being reused/closed incorrectly by the caller.

Related errors


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