# pa11y error ssl certificate failed on staging url - how to fix it

## TL;DR

Tell Chromium to accept the staging certificate: pass --chrome-flags with --ignore-certificate-errors, or better, fix the staging cert. Self-signed and expired certs on staging are the norm, and pa11y's browser refuses them by default. One line of why: pa11y is a browser, and browsers distrust bad certs, so the scan never starts.

## The error, verbatim

```text
Error: SSL certificate failed for https://staging.example.com/
    net::ERR_CERT_AUTHORITY_INVALID

```

## Fix it step by step

### Step 1: Reproduce the cert error

```bash
npx pa11y https://staging.example.com/ | rg -i 'ssl|cert' | head -3
```

Expected: The SSL certificate error repeats.

### Step 2: Inspect the certificate

```bash
echo | openssl s_client -connect staging.example.com:443 -servername staging.example.com | openssl x509 -noout -issuer -dates
```

Expected: Shows the issuer and dates; self-signed or expired confirms the staging-cert story.

### Step 3: Bypass for staging scans

```bash
npx pa11y https://staging.example.com/ --chrome-flags='--ignore-certificate-errors' --reporter cli | tail -3
```

Expected: Scan runs past the cert error and reports real violations.

### Step 4: Persist in CI config

```bash
node -e "const fs=require('fs'); const c=JSON.parse(fs.readFileSync('.pa11yci.json','utf8')); c.defaults=c.defaults||{}; c.defaults.chromeFlags=['--ignore-certificate-errors']; fs.writeFileSync('.pa11yci.json', JSON.stringify(c,null,2)); console.log('saved')"
```

Expected: The bypass is saved for staging runs only.

### Step 5: Re-run twice to rule out flakes

```bash
npx pa11y https://example.com/ | tail -2
```

Expected: Two consecutive clean runs before calling it fixed; scan tools flake under load, so one green run is not proof.

## When to use this skill

- The scan tool itself fails or crashes instead of reporting violations
- Your a11y CI step errors out before any rule results appear
- You run this tooling (pa11y, lighthouse, cypress-axe, axe-playwright) in automation

## When NOT to use this skill

- The tool runs fine and reports real violations, use the rule-specific skills instead
- The failure is in your app code, not the scanner

## Compatibility

pa11y 6.x / pa11y-ci 3.x. The --chrome-flags passthrough controls Chromium behavior. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### pa11y ssl certificate failed staging

Same error, same bypass.

### pa11y err_cert_authority_invalid

The underlying Chromium error, same fix.

### same failure locally and in CI

Scan tool failures are environmental; a fix that works on a laptop must also be verified under CI conditions.

## Why it happens

Staging environments use self-signed certificates, internal CAs, or expired certs, and Chromium (which pa11y drives) rejects them with ERR_CERT_AUTHORITY_INVALID or ERR_CERT_DATE_INVALID. The scan fails before any audit runs. The bypass flag is appropriate for staging scans in CI, but the real fix for a long-lived staging environment is a proper certificate from an internal CA the CI trust store knows. Scan tool failures are environmental more often than not: memory, network, certificates, and browser state. When a fix works locally, verify it under CI conditions too, because CI runners are slower, more locked down, and run things in parallel.

## Edge cases

- Only bypass certs for staging and dev scans, never for production URLs.
- If staging uses an internal CA, add the CA to the CI trust store instead of bypassing, it is barely more work.
- Expired certs on staging still deserve a ticket, the bypass hides the rot.
- Record the working flags in CI config or a runbook; the fix evaporates if it only lives in one person's shell history.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst__SJbzJ-39LtviSjGOnG9dw
