# PEM routines::no start line

The error `PEM routines::no start line` means OpenSSL expected a PEM file and could not find a `-----BEGIN` header in it. There are three causes. Most often the file is DER-encoded and you need to add `-inform der`. Sometimes the file is PEM but holds a different object than the subcommand parses — `openssl x509` on a CSR, for example. Occasionally the file is genuinely corrupt, empty, or an HTML error page a download saved under a `.crt` name.

Source: https://certguru.io/errors/pem-routines-no-start-line/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

> **The exact message**
>
> ```
>   unable to load certificate
>   40E7B1F701000000:error:1E08010C:DECODER routines::unsupported:...
>   ...:PEM routines::no start line:crypto/pem/pem_lib.c:...
>   ```
>   Older OpenSSL versions phrase it as `PEM_read_bio_X509: no start line`.

## What it means

OpenSSL opened the file, scanned for a line beginning `-----BEGIN`, and reached the end without
finding one. That is the entire failure. It has not looked at the certificate, checked a signature
or evaluated trust — it could not get as far as parsing.

## Cause 1 — the file is DER, not PEM

This accounts for most occurrences. OpenSSL assumes PEM input unless told otherwise, so a binary
file produces exactly this error.

*Check the first two bytes*

```bash
head -c 2 certificate.crt | xxd
```

Expected output:

```
00000000: 3082                                     0.
```

`30 82` is DER. The fix is one flag (the file is named `binary.crt` here to keep it distinct
from the PEM example above):

```bash
openssl x509 -inform der -in binary.crt -noout -text
```

Or convert it once and stop thinking about it:

```bash
openssl x509 -inform der -in binary.crt -out certificate.pem
```

See [convert DER to PEM](/convert/der-to-pem/).

## Cause 2 — right encoding, wrong subcommand

Each OpenSSL subcommand parses one object type. Giving `openssl x509` a CSR produces this error even
though the file is perfectly good PEM.

```bash
head -n1 mystery.pem
```

Expected output:

```
-----BEGIN CERTIFICATE REQUEST-----
```

| BEGIN label | Correct subcommand |
| --- | --- |
| `CERTIFICATE` | `openssl x509` |
| `CERTIFICATE REQUEST` | `openssl req` |
| `PRIVATE KEY` / `ENCRYPTED PRIVATE KEY` | `openssl pkey` |
| `RSA PRIVATE KEY` | `openssl rsa` or `openssl pkey` |
| `EC PRIVATE KEY` | `openssl ec` or `openssl pkey` |
| `PUBLIC KEY` | `openssl pkey -pubin` |
| `PKCS7` | `openssl pkcs7` |
| `X509 CRL` | `openssl crl` |
| `OPENSSH PRIVATE KEY` | Not an OpenSSL format — use `ssh-keygen` |

## Cause 3 — the file is not what you think

*Is it empty?*

```bash
wc -c certificate.crt
```

*Is it actually an HTML error page?*

```bash
head -c 100 certificate.crt
```

A download that returned a 404 page, a login redirect, or a truncated transfer will happily save
itself as `certificate.crt`. It happens more often than it should.

## Invisible damage

If the file *looks* right but still fails, something non-printing is in the way:

*Look at the raw first bytes*

```bash
head -c 16 certificate.crt | xxd
```

Expected output:

```
00000000: 2d2d 2d2d 2d42 4547 494e 2043 4552 5449  -----BEGIN CERTI
```

If you see `efbbbf` before the dashes, that is a UTF-8 byte order mark:

*Strip a BOM*

```bash
sed -i '1s/^\xEF\xBB\xBF//' certificate.crt
```

And for Windows line endings, which some strict parsers reject:

```bash
tr -d '\r'  certificate-fixed.crt
```

## A command that just works

When you do not control what you are handed, try PEM and fall back to DER:

```bash
openssl x509 -in "$f" -noout -text 2>/dev/null \
  || openssl x509 -inform der -in "$f" -noout -text
```


## Frequently asked questions

### What does the "40E0..." number before the message mean?

It is an OpenSSL error code identifying the internal routine that failed. It carries no information you can act on beyond the text of the message itself, so you can ignore it.

### Why does the error mention "Expecting&#58; TRUSTED CERTIFICATE"?

OpenSSL lists the PEM labels the subcommand would have accepted. It is telling you what it wanted, which is a useful hint that you are running the wrong subcommand for the file you have.

### My file definitely starts with BEGIN CERTIFICATE — why the error?

Check for invisible damage. A UTF-8 byte order mark before the dashes, Windows line endings in a strict parser, or leading whitespace will all defeat the match. `head -c 16 file | xxd` shows what is really at the start.

### Can this happen with a private key?

Yes, and the usual cause is the same — a DER key without `-inform der`. It also happens when an OpenSSH key is passed to OpenSSL, since `BEGIN OPENSSH PRIVATE KEY` is not a format OpenSSL parses.


## References

- [RFC 7468: textual encodings of PKIX structures](https://www.rfc-editor.org/rfc/rfc7468) — defines the PEM armour and what may sit between the BEGIN and END lines

## Related pages

- https://certguru.io/convert/der-to-pem/
- https://certguru.io/formats/der/
- https://certguru.io/errors/bad-decrypt/
- https://certguru.io/errors/wrong-version-number/
- https://certguru.io/formats/pem/
- https://certguru.io/convert/crt-to-pem/
- https://certguru.io/openssl/view-certificate/

--
CertGuru — https://certguru.io
