{"record":{"id":"b8dc04cdce0f3777","repo":"hyperledger/fabric","slug":"panic-err-b8dc04","errorCode":null,"errorMessage":"panic(err)","messagePattern":"panic\\(err\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/peer/common/common.go","lineNumber":105,"sourceCode":"type CommonClient struct {\n\tclientConfig comm.ClientConfig\n\taddress      string\n}\n\nfunc newCommonClient(address string, clientConfig comm.ClientConfig) (*CommonClient, error) {\n\treturn &CommonClient{\n\t\tclientConfig: clientConfig,\n\t\taddress:      address,\n\t}, nil\n}\n\nfunc (cc *CommonClient) Certificate() tls.Certificate {\n\tif !cc.clientConfig.SecOpts.RequireClientCert {\n\t\treturn tls.Certificate{}\n\t}\n\tcert, err := cc.clientConfig.SecOpts.ClientCertificate()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn cert\n}\n\n// Dial will create a new gRPC client connection to the provided\n// address. The options used for the dial are sourced from the\n// ClientConfig provided to the constructor.\nfunc (cc *CommonClient) Dial(address string) (*grpc.ClientConn, error) {\n\treturn cc.clientConfig.Dial(address)\n}\n\nfunc init() {\n\tGetEndorserClientFnc = GetEndorserClient\n\tGetDefaultSignerFnc = GetDefaultSigner\n\tGetBroadcastClientFnc = GetBroadcastClient\n\tGetOrdererEndpointOfChainFnc = GetOrdererEndpointOfChain\n\tGetDeliverClientFnc = GetDeliverClient\n\tGetPeerDeliverClientFnc = GetPeerDeliverClient","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/common/common.go#L87-L123","documentation":"CommonClient.Certificate retrieves the client TLS certificate from the security options; if SecOpts.ClientCertificate() returns an error (e.g. the configured cert/key files cannot be loaded or parsed), the code panics rather than returning an error. This is an intentional unrecoverable failure: the client was configured to require a client cert but none can be obtained.","triggerScenarios":"Constructing a CommonClient with SecOpts.RequireClientCert=true but the ClientCertificate() call fails because tls client cert/key file paths are wrong, files unreadable, or key/cert mismatch.","commonSituations":"CORE_VM/CLI config pointing to nonexistent cert paths; expired or malformed PEM files; key and cert pair mismatched; running in a container without the mounted certificate volume.","solutions":["Check that the client certificate and key file paths in config (SecOpts) exist and are readable","Verify the key matches the certificate (re-export the pair from your MSP if unsure)","Ensure RequireClientCert is only true when valid client credentials are actually configured","Wrap client construction early so the panic happens at startup, not mid-operation"],"exampleFix":"// before\n// SecOpts{RequireClientCert: true, Key: nil} -> panic(err)\n// after\nsecOpts := &fab.CommonClientConfig.SecOpts\nsecOpts.RequireClientCert = true\nsecOpts.ClientCertFile = \"/path/to/client.crt\"\nsecOpts.ClientKeyFile = \"/path/to/client.key\" // valid, matching pair","handlingStrategy":"validation","validationCode":"// validate cert material before constructing the client\ncertFile, keyFile := cfg.ClientCertFile, cfg.ClientKeyFile\nif certFile == \"\" || keyFile == \"\" { return errors.New(\"client cert/key required when RequireClientCert=true\") }\nif _, err := tls.LoadX509KeyPair(certFile, keyFile); err != nil {\n    return fmt.Errorf(\"invalid client cert/key: %w\", err)\n}","typeGuard":"func hasValidClientCert(opts *SecOpts) bool {\n    if !opts.RequireClientCert { return true }\n    cert, err := opts.ClientCertificate()\n    return err == nil && len(cert.Certificate) > 0\n}","tryCatchPattern":"func safeCertificate(cc *common.CommonClient) (cert tls.Certificate, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"client certificate unavailable: %v\", r)\n        }\n    }()\n    return cc.Certificate(), nil\n}","preventionTips":["Verify cert/key file paths exist and are readable before starting the client","Check that key and certificate form a matching pair (compare public keys)","Recover() around panicking client setup in long-running services","Keep RequireClientCert=false unless valid client credentials are guaranteed"],"tags":["tls","panic","configuration","hyperledger-fabric"],"backgroundTag":"missing-client-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"}