hyperledger/fabric · error

illegal file mode detected for file %s: %o

Error message

illegal file mode detected for file %s: %o

What it means

Each file entry's tar mode must contain only regular-file and rw-rw-rw- permission bits (0o100666 mask). Any entry with extra bits — setuid/setgid, sticky, directory, symlink, or executable bits — is rejected to keep packages safe to extract.

Source

Thrown at core/chaincode/platforms/java/platform.go:83

		// --------------------------------------------------------------------------------------
		// Check name for conforming path
		// --------------------------------------------------------------------------------------
		if !filesToMatch.MatchString(header.Name) || filesToIgnore.MatchString(header.Name) {
			return fmt.Errorf("illegal file detected in payload: \"%s\"", header.Name)
		}

		// --------------------------------------------------------------------------------------
		// Check that file mode makes sense
		// --------------------------------------------------------------------------------------
		// Acceptable flags:
		//      ISREG      == 0100000
		//      -rw-rw-rw- == 0666
		//
		// Anything else is suspect in this context and will be rejected
		// --------------------------------------------------------------------------------------
		if header.Mode&^0o100666 != 0 {
			return fmt.Errorf("illegal file mode detected for file %s: %o", header.Name, header.Mode)
		}
	}
	return nil
}

// WritePackage writes the java chaincode package
func (p *Platform) GetDeploymentPayload(path string) ([]byte, error) {
	logger.Debugf("Packaging java project from path %s", path)

	if path == "" {
		logger.Error("ChaincodeSpec's path cannot be empty")
		return nil, errors.New("ChaincodeSpec's path cannot be empty")
	}

	// trim trailing slash if it exists
	if path[len(path)-1] == '/' {
		path = path[:len(path)-1]
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Package only regular files, not directory entries
  2. Normalize file modes to 0666 (or 0644) before tarring: `chmod -R a-x` then set perms, or use a packaging script that forces modes
  3. Remove executables/symlinks/special files from the packaged tree
  4. Build the tar programmatically (like util.WriteFolderToTarPackage) forcing regular-file headers

Example fix

// before
exec.Command("tar", "-czf", "pkg.tgz", "src", "pom.xml") // includes dirs, exec bits
// after
// use a writer that emits only regular-file headers with mode 0644, e.g. the SDK's packaging utilities
Defensive patterns

Strategy: validation

Validate before calling

func precheckTarModes(tarPath string) error {
    f, _ := os.Open(tarPath); defer f.Close()
    gr, err := gzip.NewReader(f); if err != nil { return err }
    tr := tar.NewReader(gr)
    for {
        h, err := tr.Next()
        if err == io.EOF { return nil }
        if err != nil { return err }
        if h.Mode&^0o100666 != 0 { return fmt.Errorf("bad mode %o on %s", h.Mode, h.Name) }
    }
}

Try / catch

if err := platform.ValidateCodePackage(code); err != nil {
    if strings.Contains(err.Error(), "illegal file mode detected") {
        // rebuild tar forcing mode 0644 headers
    }
}

Prevention

When it happens

Trigger: ValidateCodePackage reads a tar header where header.Mode &^ 0o100666 != 0, e.g. directories (ISDIR bit), executables (0755 x bits), or special files inside the package.

Common situations: Tarring a directory tree with `tar -czf` so directory entries are included; packaging scripts or build artifacts with +x permissions; using system tar with preservation of special file modes (setgid dirs).

Related errors


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