{"record":{"id":"d7bb59cbde382d71","repo":"hyperledger/fabric","slug":"cannot-load-identity-for-consenter-s-d-s","errorCode":null,"errorMessage":"cannot load identity for consenter %s:%d: %s","messagePattern":"cannot load identity for consenter (.+?):(.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configtxgen/encoder/encoder.go","lineNumber":279,"sourceCode":"\t\t\tclientCert, err := os.ReadFile(consenter.ClientTLSCert)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot load client cert for consenter %s:%d: %s\", c.GetHost(), c.GetPort(), err)\n\t\t\t}\n\t\t\tc.ClientTlsCert = clientCert\n\t\t}\n\n\t\tif consenter.ServerTLSCert != \"\" {\n\t\t\tserverCert, err := os.ReadFile(consenter.ServerTLSCert)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot load server cert for consenter %s:%d: %s\", c.GetHost(), c.GetPort(), err)\n\t\t\t}\n\t\t\tc.ServerTlsCert = serverCert\n\t\t}\n\n\t\tif consenter.Identity != \"\" {\n\t\t\tidentity, err := os.ReadFile(consenter.Identity)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot load identity for consenter %s:%d: %s\", c.GetHost(), c.GetPort(), err)\n\t\t\t}\n\t\t\tc.Identity = identity\n\t\t}\n\n\t\tconsenterProtos = append(consenterProtos, c)\n\t}\n\treturn consenterProtos, nil\n}\n\n// NewConsortiumOrgGroup returns an org component of the channel configuration.  It defines the crypto material for the\n// organization (its MSP).  It sets the mod_policy of all elements to \"Admins\".\nfunc NewConsortiumOrgGroup(conf *genesisconfig.Organization) (*cb.ConfigGroup, error) {\n\tconsortiumsOrgGroup := protoutil.NewConfigGroup()\n\tconsortiumsOrgGroup.ModPolicy = channelconfig.AdminsPolicyKey\n\n\tif conf.SkipAsForeign {\n\t\treturn consortiumsOrgGroup, nil\n\t}","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/configtxgen/encoder/encoder.go#L261-L297","documentation":"configtxgen's consenterProtosFromConfig builds orderer consenters for the genesis block. When a consenter entry in configtx.yaml specifies an Identity path, the file must be readable; otherwise the encoder aborts group creation with this wrapped os.ReadFile error.","triggerScenarios":"An Orderer's Org consenter in the OrdererGroup config has Consenter.Identity set to a TLS root-cert/identity file path that does not exist, is a relative path resolved from the wrong working directory, or is unreadable due to file permissions.","commonSituations":"Running configtxgen with -configPath different from where the crypto material was generated; using relative paths in configtx.yaml while invoking from another directory; incomplete cryptogen output; mounting only part of the crypto-config volume in a container.","solutions":["Fix the Identity path in configtx.yaml (Consenter.Identity) to point to the existing certificate file, or use FABRIC_CFG_PATH/-configPath so relative paths resolve.","Verify the file exists and is readable: ls -l <path> and check ownership/permissions.","Regenerate crypto material with cryptogen if the MSP/tls directory tree is incomplete or stale.","Set Identity to \"\" if the consenter genuinely has no identity file; the field is optional."],"exampleFix":"// before (configtx.yaml)\nConsenters:\n  - Host: orderer.example.com\n    Port: 7050\n    Identity: ./crypto-config/ordererOrganizations/example.com/tlsca/server.crt\n// after (path that actually exists relative to where configtxgen runs)\nConsenters:\n  - Host: orderer.example.com\n    Port: 7050\n    Identity: /full/path/crypto-config/ordererOrganizations/example.com/tlsca/server.crt","handlingStrategy":"validation","validationCode":"const identityPath := consenter.Identity\nif identityPath != \"\" {\n    if _, err := os.Stat(identityPath); err != nil {\n        return fmt.Errorf(\"consenter identity file not accessible at %s: %w\", identityPath, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, err := os.ReadFile(consenter.Identity); err != nil {\n    // fail fast with a clear message naming the path from configtx.yaml\n    return fmt.Errorf(\"cannot read consenter identity %q: %w\", consenter.Identity, err)\n}","preventionTips":["Use absolute paths for Consenter.Identity in configtx.yaml","Always run configtxgen from the directory containing the referenced crypto material or set -configPath","Verify with `cryptogen` that all TLS/identity files were generated before running configtxgen","In CI, add a step that checks the existence of every file path referenced in configtx.yaml"],"tags":["hyperledger-fabric","configtxgen","file-not-found","consenter"],"backgroundTag":"file-not-found","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}