<!-- https://pkizerotohero.com/course/chains-and-trust-stores/ | Markdown mirror of the HTML page | PKI Zero to Hero, by Duyutech BV -->

> Lesson 6 of PKI in 90 minutes: trust stores and root programs, certificate chains, missing intermediates, cross-signing and private CAs.

Source: https://pkizerotohero.com/course/chains-and-trust-stores/ · Last reviewed: 2026-10-20

# Chains and trust stores

About 10 minutesCrash course

**In one sentence:**

A client trusts a certificate only if it can build a chain of signatures to a root already in its own trust store, so servers must send every intermediate.

## The situation

A new partner API works in every browser you try. The nightly import job, which uses curl, fails with `SSL certificate problem: unable to get local issuer certificate`. The developer says the certificate is fine, because the browser shows no warning.

Who is right?

## What is going on

### Trust stores: who do we trust?

Your device trusts a CA because that CA’s [root certificate](https://pkizerotohero.com/handbook/glossary/#root-certificate) is in its [trust store](https://pkizerotohero.com/handbook/glossary/#trust-store): a list of roots shipped with the operating system, the browser or the programming runtime. Root programs run by Apple, Google, Microsoft and Mozilla decide which roots go in, after audits and policy reviews, and take them out again when a CA fails (lesson 8).

A root certificate is [self-signed](https://pkizerotohero.com/handbook/glossary/#self-signed-certificate): it signs itself. That earns no trust, because anyone can make a self-signed certificate in a second. A root is trusted **only because it is already in the trust store**.

Different software uses different stores: the operating system’s store, Firefox’s own, Java’s `cacerts`, the certifi bundle used by many Python libraries, and the list built into Node.js. The same server can be trusted by one client and rejected by another.

### Chains: from the leaf to a root

Roots rarely sign website certificates directly. Their keys are usually kept offline, so a root signs an [intermediate](https://pkizerotohero.com/handbook/glossary/#intermediate-certificate) CA certificate, and the intermediate signs the website’s [leaf certificate](https://pkizerotohero.com/handbook/glossary/#leaf-certificate).

*Diagram: A chain: the leaf certificate for api.example.com is issued by an intermediate CA, which is issued by a root CA. The server sends the leaf and the intermediate. The root is already in the client's trust store. If the intermediate is missing, browsers may fetch it and carry on, marked with a tick, while curl, Java and Python fail, marked with a cross.*

The server sends the leaf and the intermediates. The client supplies the root from its own trust store.

To accept the leaf, the client builds a [certificate chain](https://pkizerotohero.com/handbook/glossary/#certificate-chain): leaf, then each intermediate, ending at a root in its own store. It checks every signature along the way, every validity period, and that each issuer is allowed to act as a CA.

The **server’s job** is to send its leaf plus every intermediate. It does not need to send the root: the client must already have it, and a root that arrives from the server is not trusted just because it was sent.

### Why the browser fooled the developer

Browsers often repair a missing intermediate silently. They may fetch it from the address listed in the leaf’s [Authority Information Access](https://pkizerotohero.com/handbook/glossary/#authority-information-access) extension, or use a copy they already have. Most non-browser clients, such as curl built with OpenSSL, Java and Python, do not, by default. So “it works in my browser” proves little about the chain. In the situation, the job is right to fail, and the fix belongs on the server.

### Two roads to the same root

A new root takes years to reach every device. Meanwhile, a CA can have its new root or intermediate signed by an older, widely trusted root as well. This [cross-signing](https://pkizerotohero.com/handbook/glossary/#cross-signing) gives old devices one valid road and new devices another. When the old root expires, devices that know only the old road start to fail. This happened to some older devices when DST Root CA X3, the older root that had cross-signed Let’s Encrypt, expired on 30 September 2021.

### Your own CA

Certificates from a private, internal CA work only on devices where your root has been installed. The fix for a failing client is to install that root through a managed process, never to switch off certificate checking.

Why it matters to the business

Ask your team

Do our servers send their full chain, and do we test with a non-browser client such as curl? Which trust stores do our applications use, and how do we keep them up to date?

## Try it

*Interactive tool: Chain checker (runs in the browser at [/tools/chain/](https://pkizerotohero.com/tools/chain/))*

This server sends its leaf but not the intermediate. Find where the chain breaks between the leaf and a trusted root, and note which kind of client would still connect and which would fail.

## Check

Check yourself

In the situation, the API works in browsers but curl fails with 'unable to get local issuer certificate'. Who is right?

1. The developer: the certificate is fine, so curl is broken
2. Nobody: certificate checking should be turned off for this host
3. curl: the server is not sending its intermediate, and browsers were hiding the gap

Show answer

Answer C curl: the server is not sending its intermediate, and browsers were hiding the gap

What happened

The server sends only its leaf. curl cannot link it to a root in its CA bundle, so it stops.

Why

Browsers often fetch or reuse a missing intermediate. curl relies on what the server sends plus its own trust store, so it exposes the server's mistake.

The rule

The server must send its leaf plus every intermediate. Never fix a chain error by turning verification off.

Check yourself

Why is a root CA certificate trusted?

1. Because it is already in the trust store of the device or application
2. Because it is self-signed
3. Because the server sends it at the end of the chain

Show answer

Answer A Because it is already in the trust store of the device or application

What happened

It is trusted because the device or application already has it in its trust store.

Why

Self-signing proves nothing: anyone can make a self-signed certificate. Root programs decide which roots are shipped, and a root sent by the server gains no trust from being sent.

The rule

A root is trusted only because it is already in the trust store, not because it is self-signed.

Check yourself

An internal app uses a certificate from your company's private CA. It works on managed laptops but fails on a contractor's laptop. What is the right fix?

1. Tell the contractor to click through the warning
2. Install the company root in the contractor's trust store through an approved process, or provide a managed device
3. Make the server send the root certificate as well

Show answer

Answer B Install the company root in the contractor's trust store through an approved process, or provide a managed device

What happened

The contractor's device lacks your private root, so it cannot finish the chain. Installing that root through an approved process fixes it.

Why

Managed laptops received the root through device management. Clicking through teaches people to ignore real attacks, and sending the root from the server does not make it trusted.

The rule

Private CAs work only where their root is installed; distribute the root deliberately, never bypass the check.

## Takeaways

- Trust starts in the trust store: a root is trusted only because it is already there, and different software has different stores.
- The client builds a chain from the leaf to a trusted root; the server must send every intermediate.
- “Works in my browser” proves little. Test with curl or your real client, and never switch off verification.

## Go further

- Handbook: [Who do we trust? CAs, trust stores and self-signed certificates](https://pkizerotohero.com/handbook/trust-stores/)
- Handbook: [Certificate chains and path validation](https://pkizerotohero.com/handbook/certificate-chains/)
- Handbook: [Two roads to the same root: cross-signing and root expiry](https://pkizerotohero.com/handbook/cross-signing/)
- Error: [curl: unable to get local issuer certificate](https://pkizerotohero.com/errors/curl-unable-to-get-local-issuer-certificate/)
- Next lesson: [The handshake and its errors](https://pkizerotohero.com/course/handshake-and-errors/)

**Early edition.** Checked against the standards; an independent expert review is in progress. Found a mistake? [Tell us](https://pkizerotohero.com/contact/?topic=content-error&page=/course/chains-and-trust-stores/).

Last reviewed 20 October 2026Edition 0.9

## Go deeper in the handbook

- [Chapter 12: Who do we trust? CAs, trust stores and self-signed certificates](https://pkizerotohero.com/handbook/trust-stores/)
- [Chapter 13: Certificate chains and path validation](https://pkizerotohero.com/handbook/certificate-chains/)
- [Chapter 14: Two roads to the same root: cross-signing and root expiry](https://pkizerotohero.com/handbook/cross-signing/)
