arduino/Arduino · error · CertificateError
hostname %r doesn't match %r
Error message
hostname %r doesn't match %r
What it means
ssl_match_hostname.match_hostname verifies that the hostname you connected to matches the CommonName or subjectAltName entries in the server's TLS certificate. This CertificateError is raised when the certificate is valid in form but none of its DNS names match the hostname you requested. It is urllib3's vendored copy of Python's stdlib match_hostname, called from connect() during the TLS handshake.
Source
Thrown at arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py:56
return
dnsnames.append(value)
if not dnsnames:
# The subject is only checked when there is no dNSName entry
# in subjectAltName
for sub in cert.get('subject', ()):
for key, value in sub:
# XXX according to RFC 2818, the most specific Common Name
# must be used.
if key == 'commonName':
if _dnsname_to_pat(value).match(hostname):
return
dnsnames.append(value)
if len(dnsnames) > 1:
raise CertificateError("hostname %r "
"doesn't match either of %s"
% (hostname, ', '.join(map(repr, dnsnames))))
elif len(dnsnames) == 1:
raise CertificateError("hostname %r "
"doesn't match %r"
% (hostname, dnsnames[0]))
else:
raise CertificateError("no appropriate commonName or "
"subjectAltName fields were found")
View on GitHub (pinned to a0df6e0e83)
Solutions
- Use the exact hostname listed in the certificate's subjectAltName (check with `openssl s_client -connect host:443 -servername host | openssl x509 -text | grep -A1 'Subject Alternative Name'`).
- Fix DNS so the correct certificate is served (SNI-aware client, correct vhost config).
- Reissue the certificate adding the needed SAN entry (e.g. wildcard or the www/internal name).
- As a last resort for trusted-but-mismatched internal endpoints, set cert_reqs='CERT_NONE' or assert_hostname to an expected value via a custom HTTPSConnectionPool — never for untrusted traffic.
Example fix
// before
import urllib3
http = urllib3.PoolManager()
r = http.request('GET', 'https://10.0.0.5/api') # cert is for api.internal.example.com
// after
r = http.request('GET', 'https://api.internal.example.com/api') # hostname matches cert SAN Defensive patterns
Strategy: validation
Validate before calling
import socket
from urllib.parse import urlparse
host = urlparse(url).hostname
if host is None or _looks_like_ip(host):
raise ValueError('Connect by the certificate hostname, not an IP: %s' % host)
def _looks_like_ip(h):
try:
socket.inet_aton(h)
return True
except socket.error:
return False Try / catch
from requests.exceptions import SSLError
try:
resp = requests.get(url, timeout=10)
except SSLError as e:
if 'doesn\'t match' in str(e):
log.error('Hostname/cert mismatch for %s: %s', url, e)
raise Prevention
- Always connect using the DNS name on the certificate, never a bare IP.
- Run `openssl s_client -servername <host>` in CI to assert SANs cover every environment hostname.
- Keep staging certs issued with the same SANs as production.
- Prefer verify=True (default) and fix certs rather than disabling verification.
When it happens
Trigger: Calling urllib3/requests against https://host while the server presents a certificate whose subjectAltName/CN list contains DNS names, but none equal (or wildcard-match) the requested hostname; e.g. connecting via IP address, a CNAME alias, or 'www.example.com' when the cert only covers 'example.com'.
Common situations: Typo in the URL hostname; accessing a load balancer or internal service by IP instead of the name on the cert; server misconfigured to serve the wrong vhost/cert; SNI-less clients hitting a shared host that returns a default cert for another domain; self-signed or staging certs without the required SAN.
Related errors
- no appropriate commonName or subjectAltName fields were foun
- SSLError(e)
- SSLError(e)
- Can't connect to HTTPS URL because the SSL module is not ava
- empty or no certificate
AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06).
Data as JSON: /api/errors/c545ce62e82d187f.
Report an issue: GitHub.