Inspect and debug TLS certificate chains (without OpenSSL)
With Homebrew:
$ brew install x52dev/tap/inspect-cert-chainWith cargo-binstall:
$ cargo binstall inspect-cert-chainFrom source:
$ cargo install inspect-cert-chainFrom a remote TLS server:
inspect-cert-chain --host <hostname>Remote fetching gets the certificate chain from the TLS handshake. It supports any application protocol on servers that start TLS as soon as the connection opens.
The default port is 443. Use --port to inspect a TLS service on another port:
inspect-cert-chain --host <hostname> --port <port>Services that require a plaintext exchange before TLS, such as STARTTLS, are not supported.
To connect to a specific IP address with a different TLS server name (SNI):
inspect-cert-chain --host 192.0.2.10 --server-name staging.example.com--host selects the connection target. --server-name sets the TLS server name; it defaults to --host and requires --host. IPv6 addresses are also supported, for example --host 2001:db8::10.
Remote fetching has a 10s overall timeout. Use --timeout <DURATION> to change it, for example 500ms, 30s, or 2m. The duration must be greater than zero.
From chain file:
inspect-cert-chain --file <path>From stdin:
cat <path> | inspect-cert-chain --file -Use --check to check the validity dates of every certificate in the chain. It checks that the current time is between not_before and not_after, inclusive. It does not verify signatures, hostname matches, trust roots, or revocation.
inspect-cert-chain --host example.com --check
inspect-cert-chain --file chain.pem --checkCheck mode uses these exit codes:
| Code | Status | Meaning |
|---|---|---|
0 |
OK | All certificates are within their validity periods and outside the thresholds |
1 |
Warning | At least one certificate is within the warning threshold |
2 |
Critical | At least one certificate has expired, is not yet valid, has an invalid validity period, or is within the critical threshold |
3 |
Unknown | Invalid options, an empty chain, or a read, parse, fetch, or output error |
The exit code reflects the most severe result across the chain. Text check mode prints a status and reason for each certificate, then a chain summary.
Without --check, certificate dates do not change the exit code. Inspection errors exit with 1, and invalid options exit with 3. Invalid options print a usage error to stderr and leave stdout empty. --help and --version exit with 0. Interactive mode cannot be combined with --check.
Use --warn-within and --critical-within to set expiry thresholds for check mode.
inspect-cert-chain --host example.com --check --warn-within 30d --critical-within 7dBoth options require --check. Each option accepts a non-negative duration such as 30d, 12h, or 500ms. A certificate at or inside a threshold gets that status. A critical result takes precedence over a warning. If you set both thresholds, the critical duration must not exceed the warning duration. No expiry threshold applies by default.
Use --fields to select certificate fields. You can use a comma-separated list or repeat the option. Text keeps the full OpenSSL-like output when you omit it. Field selection does not change the check result or omit the chain summary. Interactive mode cannot be combined with --fields.
inspect-cert-chain --file chain.pem --fields subject,issuer,not_after
inspect-cert-chain --file chain.pem --check --fields subject,not_after,statusText prints the fields in the requested order. It prints strings without quotes, and objects and arrays as compact JSON values.
| Field | Value |
|---|---|
subject |
Distinguished name string |
issuer |
Distinguished name string |
version |
X.509 version number (1, 2, or 3) |
serial_number |
Hex string |
signature_algorithm |
Object with oid and name |
not_before |
UTC date string, for example 2026-10-02T12:00:00Z |
not_after |
UTC date string |
expires_in_seconds |
Signed number of whole seconds until expiry |
subject_alt_names |
Array of names, for example DNS:example.com or IP:127.0.0.1 |
public_key |
Object with algorithm (oid and name) and hex value |
extensions |
Array of objects with oid, name, critical, and hex value |
signature |
Hex string |
status |
Object with level (ok, warning, critical) and reason |
Hex strings use lowercase digits with no separators. Extension value contains the DER-encoded extension value. An absent subject alternate name extension gives an empty array. For expired certificates, expires_in_seconds is negative. The status field reports validity dates; it does not confirm certificate trust.
Use --json to write a JSON object with a certificates array. The array keeps the order from the host or input file. JSON includes all certificate fields from the table above when you omit --fields. Logs and error details go to stderr, including when you use -v. Interactive mode cannot be combined with --json.
inspect-cert-chain --host example.com --json
inspect-cert-chain --file chain.pem --json --fields subject,not_after
inspect-cert-chain --file chain.pem --check --json --fields subject,not_after,statusFor example, --json --fields subject,not_after returns:
{
"certificates": [
{
"subject": "CN=example.com",
"not_after": "2026-12-31T23:59:59Z"
}
]
}With --check, JSON adds a top-level "check": { "status": "ok" } object. After options pass validation, a JSON input, fetch, or dump error returns an error string. Check mode also returns "check": { "status": "unknown" }. Invalid options leave stdout empty. JSON does not change the exit codes.
Run just test-remote to inspect the hosts in tests/fixtures/remote-hosts.txt. This manual check requires internet access and reports all failures before it exits. Each host has a 30-second time limit. Use just test-remote 10s to change this limit. You can pass a different fixture as the second argument.
The CLI does not validate certificates. It must inspect expired certificates, self-signed certificates, and certificates for another hostname from BadSSL. Unsupported TLS versions, unsupported cipher suites, and oversized handshake messages must fail with the specified TLS error. DNS errors and timeouts do not count as expected TLS failures.
- OpenSSL-like text info.
- Fetch certificate chain from remote host.
- Read certificate chain from file and stdin.
- Interpret standard X.509 extensions.
- Option to read local chain files.
- Determine chain validity.