arduino/Arduino · critical · CertificateError

hostname %r doesn't match either of %s

Error message

hostname %r doesn't match either of %s

What it means

match_hostname() raises CertificateError("hostname %r doesn't match either of %s") when the connecting hostname matches none of the certificate's subjectAltName DNS entries (and none of its commonName fallbacks). This is the core TLS hostname-verification failure: the certificate presented is not valid for the name you connected to.

Source

Thrown at arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py:52

    san = cert.get('subjectAltName', ())
    for key, value in san:
        if key == 'DNS':
            if _dnsname_to_pat(value).match(hostname):
                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

  1. Inspect the cert (openssl s_client -connect host:443) and compare its SAN DNS entries with the hostname you connect to.
  2. Connect using a hostname that appears in the cert's SANs instead of the IP or an alias.
  3. Reissue the certificate including the required hostname in subjectAltName.
  4. If using an internal CA, add the host to the cert or update your DNS/aliases; never disable verification as a fix.
  5. Catch CertificateError and abort the connection rather than proceeding unverified.

Example fix

// before
sock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED)
match_hostname(sock.getpeercert(), '10.0.0.5')  # IP not in cert
// after
sock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, server_hostname='api.example.com')
match_hostname(sock.getpeercert(), 'api.example.com')
Defensive patterns

Strategy: try-catch

Validate before calling

import ssl
expected = 'api.example.com'
cert = ssl.get_server_certificate((expected, 443))  # or inspect SANs via socket
# verify expected appears in the cert's subjectAltName DNS entries before connecting

Try / catch

try:
    match_hostname(cert, hostname)
except CertificateError as e:
    log.error('hostname verification failed: %s', e)
    raise  # abort the connection; do not proceed unverified

Prevention

When it happens

Trigger: Connecting to 'api.example.com' with a cert whose SANs only cover 'example.com' or other hosts; using an IP address as hostname when the cert lists DNS names only; connecting via a hostname not listed in a self-signed or internal-CA cert; wildcard mismatch such as cert '*.example.com' vs 'a.b.example.com'.

Common situations: Internal services using certs issued for different hostnames; staging environments reusing production certs; missing SAN entries on newly issued certs (CN-only certs also fail when CN doesn't match); tools that disabled verification in dev then hit real verification in prod.

Related errors


AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06). Data as JSON: /api/errors/16685585881b069a. Report an issue: GitHub.