qgis fails to open remote files on Windows with GDAL over HTTPs

■ We describe a bug in qgis’s GDAL/curl installation.

■ We give two possible user-space solutions to the problem.

At the bottom of this page, we introduce a gpsinfo helper to work-around the problem.

The Problem

qgis employs GDAL for opening raster files. GDAL’s virtual file system allows to load remote files via curl by prefixing the filepath with /vsicurl/. But when attempting to open a raster file over a network, qgis reports

RuntimeError: CURL error: SSL certificate problem: unable to get local issuer certificate

If you are unlucky and further prefixing the filepath with /vsizip/ as you are accessing a compressed file, qgis reports

RuntimeError: `/vsizip//vsicurl/https://raw.githubusercontent.com/.../some_file.asc.zip' does not exist in the file system, and is not recognized as a supported dataset name.

The error may remain when replacing https with http in the URL, as more and more services such as github redirect requests over HTTP to HTTPs.

Both testing from qgis‘ python console

import gdal 
gdal.UseExceptions() 
gdal.Open("/vsicurl/https://raw.githubusercontent.com/.../some_file.asc")

and testing from any of Window’s command line prompts

C:\Program Files\QGIS 3.10\bin\gdalinfo.exe /vsicurl/https://raw.githubusercontent.com/.../some_file.asc

give no further hints apart from that we are facing a problem with qgis‘ distribution of GDAL/curl. The first more curl specific error message indicates problems with SSL certificates, and this is indeed a known issue with qgis.

A Proper Solution

When accessing a web server over HTTPs, you are basically utilizing encryption to secure the communication with that web server. For establishing a secure communication channel, we need to verify the web server’s identity by validating a so called SSL certificate. Above first error message tells us, that GDAL/curl are lacking the necessary SSL certificates to verify the web servers identity. So qgis sets up GDAL improperly, leaving it without the necessary certificate packages.

Luckily, python in qgis ships with certificates we may use for that purpose. Setting a environment variable with name

CURL_CA_BUNDLE

and value

C:\Program Files\QGIS 3.10\apps\Python37\Lib\site-packages\certifi\cacert.pem

tells curl to use the given file for SSL connections. After quiting any currently running qgis instances and starting qgis, you are able to load files over a HTTPs connection with GDAL/curl now.

A Quick-and-dirty Solution in Python

GDAL provides a configuration option to ignore SSL certificate errors from curl. This is a security issue, but may help in certain situations. In python, you are able to set the respecitive GDAL option

import gdal 
gdal.SetConfigOption("GDAL_HTTP_UNSAFESSL", "YES")
gdal.VSICurlClearCache()

Note the last line that clears any curl caches. Curl caches even failed download and returns the respective error, even if the configuration has changed.

gpsinfo and qgis

What does all this mean for gpsinfo’s reference implementation in python? If you are using our python module in qgis‘ python environment, remote file access over HTTPs (or services that redirect HTTP to HTTPs) may fail. We catch the respective error and print an error message referencing this page. We recommend to set the environment variable CURL_CA_BUNDLE as described above for a solution.

For a quick-and-dirty solution, you may allow unsafe SSL by calling gpsinfo’s static method

gpsinfo.Layer.allowUnsafeSSL(true)

eventually turning our four line minimal example into a six lines of code example:

import gpsinfo
service = gpsinfo.Service('http://gpsinfo.org/service_wmts/gpsinfoWMTSCapabilities.xml')
layer = gpsinfo.Layer(service, 'AT_OGD_DHM_LAMB_10M_ELEVATION_COMPRESSED')
gpsinfo.Layer.allowUnsafeSSL(true)
print('Elevation = ' + str(layer.value('nearest', 675392, 432848)))
gpsinfo.Layer.allowUnsafeSSL(false)