Search code examples
pythonsslssl-certificatewindows-subsystem-for-linuxdetectron

SSL: CERTIFICATE_VERIFY_FAILED when using pretrained detectron2 model


I am trying to just use the pretrained mask_rcnn_R_50_FPN_3x model in detectron2 on an image. I get the error ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131).

I am using Windows Subsystem for Linux. The following code produces the error.

from detectron2.config import get_cfg
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor

cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
cfg.MODEL.DEVICE='cpu'

predictor = DefaultPredictor(cfg)

I've tried updating the certifi package.
I've tried

sudo apt install ca-certificates
sudo update-ca-certificates --fresh
export SSL_CERT_DIR=/etc/ssl/certs

based on one of the answers here: https://stackoverflow.com/questions/52805115/certificate-verify-failed-unable-to-get-local-issuer-certificate.\ I've tried downloading the certificates for https://dl.fbaipublicfiles.com (by, in Google Chrome, clicking the padlock symbol -> 'Connection is secure' -> 'Certificate is valid' -> 'Details' -> 'Copy to file', and then doing the same thing for the different certificates under the 'Certification Path' tab) and copying their contents into the cacert.pem file.


UPDATE:
It seems to have something to do with the urllib.request module (altough I might be misunderstanding things). I have found that

from urllib import request
request.urlretrieve('https://dl.fbaipublicfiles.com')

(the urlretrive function is called by detectron2) results in the same error, whereas

import requests
requests.get('https://dl.fbaipublicfiles.com')

works fine.


Solution

  • Try to put this after your import statements :

    import certifi
    import ssl
    
    def create_context():
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        context.load_verify_locations(certifi.where())
        return context
    ssl._create_default_https_context = create_context
    

    This tells urllib to use certifi's certificates.