{"record":{"id":"746419f511e70364","repo":"hyperledger/fabric","slug":"tls-root-cert-file-must-be-set","errorCode":null,"errorMessage":"tls root cert file must be set","messagePattern":"tls root cert file must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/common/peerclient.go","lineNumber":67,"sourceCode":"\tsecOpts := comm.SecureOptions{\n\t\tUseTLS:             viper.GetBool(\"peer.tls.enabled\"),\n\t\tRequireClientCert:  viper.GetBool(\"peer.tls.clientAuthRequired\"),\n\t\tServerNameOverride: viper.GetString(\"peer.tls.serverhostoverride\"),\n\t}\n\n\tif secOpts.RequireClientCert {\n\t\tvar err error\n\t\tsecOpts.Key, secOpts.Certificate, err = getClientAuthInfoFromEnv(\"peer\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t}\n\tclientConfig.SecOpts = secOpts\n\n\tif clientConfig.SecOpts.UseTLS {\n\t\tif tlsRootCertFile == \"\" {\n\t\t\treturn nil, errors.New(\"tls root cert file must be set\")\n\t\t}\n\t\tcaPEM, res := os.ReadFile(tlsRootCertFile)\n\t\tif res != nil {\n\t\t\treturn nil, errors.WithMessagef(res, \"unable to load TLS root cert file from %s\", tlsRootCertFile)\n\t\t}\n\t\tclientConfig.SecOpts.ServerRootCAs = [][]byte{caPEM}\n\t}\n\n\tclientConfig.MaxRecvMsgSize = comm.DefaultMaxRecvMsgSize\n\tif viper.IsSet(\"peer.maxRecvMsgSize\") {\n\t\tclientConfig.MaxRecvMsgSize = int(viper.GetInt32(\"peer.maxRecvMsgSize\"))\n\t}\n\tclientConfig.MaxSendMsgSize = comm.DefaultMaxSendMsgSize\n\tif viper.IsSet(\"peer.maxSendMsgSize\") {\n\t\tclientConfig.MaxSendMsgSize = int(viper.GetInt32(\"peer.maxSendMsgSize\"))\n\t}\n\n\treturn newPeerClientForClientConfig(address, clientConfig)","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/common/peerclient.go#L49-L85","documentation":"When TLS is enabled for the peer connection (SecOpts.UseTLS), NewPeerClientForAddress requires a TLS root certificate file to verify the peer's server certificate. If tlsRootCertFile is empty while TLS is on, this error is thrown. It enforces that secure connections always have a trust anchor.","triggerScenarios":"Calling NewPeerClientForAddress with a TLS-enabled peer address but passing \"\" as tlsRootCertFile; TLS enabled in config (peer.tls.enabled=true) but the --tlsRootCertFile / tls root cert path not supplied.","commonSituations":"Running peer CLI commands against a TLS-enabled network without --tlsRootCertFile; config switched from TLS disabled to enabled without updating client parameters; forgetting the CA cert path when targeting a different organization's peer.","solutions":["Provide the TLS root cert: NewPeerClientForAddress(addr, \"/path/to/tlsca.cert\")","Pass --tlsRootCertFile on the CLI command pointing at the network's tlsca certificate","If TLS is genuinely disabled, check why UseTLS is true (peer.tls.enabled setting) and correct the config"],"exampleFix":"// before\nclient, err := common.NewPeerClientForAddress(\"peer0.org1.example.com:7051\", \"\")\n// after\nclient, err := common.NewPeerClientForAddress(\"peer0.org1.example.com:7051\",\n    \"../test-network/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem\")","handlingStrategy":"validation","validationCode":"func tlsCertReady(tlsRootCertFile string) error {\n    tlsEnabled := viper.GetBool(\"peer.tls.enabled\") || viper.GetBool(\"peer.tls.rootcert.file\") != \"\"\n    if tlsEnabled && tlsRootCertFile == \"\" {\n        return errors.New(\"TLS is enabled but tlsRootCertFile is empty\")\n    }\n    if tlsRootCertFile != \"\" {\n        if _, err := os.ReadFile(tlsRootCertFile); err != nil {\n            return fmt.Errorf(\"cannot read TLS root cert: %w\", err)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"client, err := common.NewPeerClientForAddress(addr, tlsRootCertFile)\nif err != nil {\n    if strings.Contains(err.Error(), \"tls root cert file must be set\") {\n        return fmt.Errorf(\"supply --tlsRootCertFile for TLS-enabled peer: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep the tlsca cert path next to the peer address in your scripts/config","Use the standard test-network path layout: organizations/peerOrganizations/<org>/tlsca/","Confirm peer.tls.enabled setting matches whether you pass a root cert"],"tags":["fabric","tls","client-config"],"backgroundTag":"missing-tls-certificate","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"}