hyperledger/fabric · error

reading from file %s failed

Error message

reading from file %s failed

What it means

readPemFile reads a file and requires its content to be PEM-decodable before returning it. This error wraps a readFile failure, so the PEM file (cert or key) referenced by the MSP config could not be read — missing file or permission problem. It is the read-stage failure; PEM decoding problems produce a different error.

Source

Thrown at msp/configbuilder.go:72

	OrganizationalUnitIdentifiers []*OrganizationalUnitIdentifiersConfiguration `yaml:"OrganizationalUnitIdentifiers,omitempty"`
	// NodeOUs enables the MSP to tell apart clients, peers and orderers based
	// on the identity's OU.
	NodeOUs *NodeOUs `yaml:"NodeOUs,omitempty"`
}

func readFile(file string) ([]byte, error) {
	fileCont, err := os.ReadFile(file)
	if err != nil {
		return nil, errors.Wrapf(err, "could not read file %s", file)
	}

	return fileCont, nil
}

func readPemFile(file string) ([]byte, error) {
	bytes, err := readFile(file)
	if err != nil {
		return nil, errors.Wrapf(err, "reading from file %s failed", file)
	}

	b, _ := pem.Decode(bytes)
	if b == nil { // TODO: also check that the type is what we expect (cert vs key..)
		return nil, errors.Errorf("no pem content for file %s", file)
	}

	return bytes, nil
}

func getPemMaterialFromDir(dir string) ([][]byte, error) {
	mspLogger.Debugf("Reading directory %s", dir)

	_, err := os.Stat(dir)
	if os.IsNotExist(err) {
		return nil, err
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the reported file exists and is readable: 'ls -l <file>' then fix path or permissions
  2. Remove dangling symlinks and re-copy valid PEM files into the MSP cert directories
  3. Ensure the fabric process user can traverse all directories in the path
  4. Regenerate the MSP directory with cryptogen/fabric-ca-server if material is missing

Example fix

// before: dangling symlink in cacerts
files from os.ReadDir include stale link -> readPemFile fails
// after
// rm cacerts/broken-link.pem
// cp valid-ca.pem cacerts/
Defensive patterns

Strategy: validation

Validate before calling

func pemFileValid(path string) error {
    b, err := os.ReadFile(path)
    if err != nil { return err }
    if pem.Decode(b) == nil { return fmt.Errorf("%s is not PEM", path) }
    return nil
}

Try / catch

b, err := readPemFile(path)
if err != nil {
    if os.IsNotExist(errors.Unwrap(err)) {
        return fmt.Errorf("recreate MSP: %s is missing", path)
    }
    return err
}

Prevention

When it happens

Trigger: getPemMaterialFromDir enumerating cacerts/admincerts/signcerts/intermediatecerts/tls dirs and calling readPemFile on an entry that disappeared or is unreadable; loadCertificateAt reading a cert path that does not exist.

Common situations: Empty or half-deleted MSP directories, dangling symlinks in cert dirs, NFS/permission issues in containers, file removed between directory listing and read.

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/8206b3a782f4bda9. Report an issue: GitHub.