Files
hq/04-ISSUES/014-a-key-that-is-present-and-unusable/00-report.md
T
jschoubben a6872ac099 A key that is present and unusable, and what the certificate work became
Issue 014: the node's serving key was stored in the host's own encoding, so
every check that reads the file passed and no server could start. Same shape as
013 — two halves of one mechanism designed separately, each correct about its
own half. Where a file exists so a third party can read it, the format is the
interface.
2026-08-31 00:42:13 +02:00

2.4 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
resolved 2026-08-31
mesh-host
mesh-host — a node's serving key is stored in the format a server reads

014 — A node's serving key was present, correct, and unusable

Symptom

A node generates the key it serves TLS with, the mesh certifies the public half, and the certificate arrives on the machine as an ordinary file. Everything about that worked. But the host stored the private half in its own encoding — base64 of the raw key — and nothing that serves TLS can read it: not a web server's ssl_certificate_key, not Go's LoadX509KeyPair, not openssl s_server -key.

The file was there, owned by root, mode 0600, holding the right key. The certificate beside it was valid and chained to the mesh's authority. The server would not start.

Why this matters

Every check that reads the file passes. The key exists, the certificate exists, the mesh recorded the public half, the machine reports the declaration applied. The failure surfaces only when something connects — the worst place to find out, and the place the certificate work was specifically designed to move away from.

It is the same shape as 013 and worth naming as a class: two halves of one mechanism designed separately, each correct about its own half. The control plane issues PEM because that is what a certificate is. The host stored the key in whatever was convenient, because nothing in the host reads it back — the whole point of the file is that something else does, and that something else was not in view.

The generalisation: where a file exists so a third party can read it, the format is not an implementation detail of whoever writes it. It is the interface, and it needs a check that reads it the way that third party will.

What was done

PKCS#8 PEM, which is what every TLS server reads. A key in the old encoding is refused by name rather than reported as corrupt — it is intact, and the remedy is to enrol again, which is a different action from repairing a damaged file.

Checked by writing a key, decoding the file as PEM, parsing it as PKCS#8, and asserting it is the same key — and, in the lab, by a real handshake from a second machine that verifies against the mesh's authority and nothing else. A key that parses is not a key a server can use, which is why the lab check connects.