Errors and log output¶
The one sentinel error you should handle¶
ErrElevationUnavailable¶
var ErrElevationUnavailable = errors.New(
"localca: administrator privileges are required to install into the system trust " +
"store, but no elevation is available (not root, and no interactive terminal to prompt)",
)
Returned when a system-store install needs administrator privileges that cannot be
obtained: the process is not root, and either sudo is missing from PATH or standard
input is not an interactive terminal.
It is the one error a consuming tool is expected to branch on, because it is not a fault —
it is the environment telling you to take a different path. Match it with errors.Is; it
survives the wrapping that Install applies:
if _, err := authority.Install(ctx); errors.Is(err, localca.ErrElevationUnavailable) {
// Fall back: NSS only, an untrusted self-signed certificate, or tell the
// user to run the install once from a terminal.
}
Everything else localca returns is a fault to report, not a condition to branch on.
Every error localca produces itself¶
All are created with github.com/cockroachdb/errors, so they carry a stack trace and
unwrap normally. Errors from the standard library or the trust-store backend are wrapped
with a short context prefix and passed through.
| Message | Returned by | What it means |
|---|---|---|
localca: Config.DataDir is required |
New, EnsureServed |
Config.DataDir was empty. |
localca: EnsureServed needs at least one host |
EnsureServed |
The hosts slice was empty. |
localca: no hosts for leaf certificate |
Authority.Leaf |
Leaf was called with no host arguments. |
localca: no root CA provisioned (call Install or EnsureServed first) |
Authority.Installed, Authority.Leaf |
No root has been minted yet. Neither call mints one. |
localca: root cert present but key missing |
any call that loads the root | rootCA.pem exists but rootCA-key.pem does not. See recovering from a half-written root. |
localca: stored root cert is not valid PEM |
any call that loads the root | rootCA.pem is not a PEM CERTIFICATE block. |
localca: stored root key is not valid PEM |
any call that loads the root | rootCA-key.pem is not a PEM EC PRIVATE KEY block. |
A leaf that fails to parse is not an error: it is treated as an empty cache and re-minted.
Wrapped errors and their prefixes¶
These prefixes tell you which step failed. The wrapped cause carries the detail.
| Prefix | Step |
|---|---|
creating data dir |
creating DataDir |
reading <file>, writing <file>, flushing <file>, setting mode on <file>, renaming <file> into place, creating temp file for <file>, removing <file> |
the atomic file write, at the named stage |
generating root key, creating root certificate, parsing root certificate, marshalling root key |
minting the root |
generating leaf key, creating leaf certificate, marshalling leaf key |
minting a leaf |
generating certificate serial |
drawing the random serial — reached when minting either the root or a leaf |
parsing stored root certificate, parsing stored root key |
loading a stored root whose PEM decoded but whose contents did not parse |
assembling leaf key pair |
turning the minted PEM into a tls.Certificate |
installing root into trust store |
the trust-store install |
removing root from trust store |
the trust-store uninstall |
encoding trust marker, writing trust marker |
updating trust-install.json |
pre-authorising sudo for the trust-store install |
the sudo -v pre-warm failed or was cancelled — typically a wrong password, or the user pressing Ctrl-C at the prompt |
installing root into trust store appears twice in a failed install: once from the
trust-store backend and once from Authority.Install wrapping it. That is cosmetic;
errors.Is and the underlying cause are unaffected.
What localca logs, and when¶
localca logs through an injected *slog.Logger. The default is a discard handler, so
nothing is logged unless you pass WithLogger.
That includes the expiry warning below, which is the only advance notice you get that your
local CA is running out.
There are exactly two lines.
INFO — a root is about to be installed¶
installing a local development CA into the trust store so this tool can serve HTTPS
locally; reverse with Uninstall
Attribute: common_name — the root's Common Name.
Emitted by Install (including the Install that EnsureServed performs) only on the
call that mints the root, immediately before the trust-store install and therefore
immediately before any password prompt. It exists so a user who is suddenly asked for a
password can see why. If you attach no logger, the prompt appears with no explanation.
Loading an existing root does not log it, so this line appears once in the life of a data directory.
WARN — the root CA is expiring¶
Attributes: common_name, and root_not_after — the root's expiry timestamp.
Emitted whenever a leaf has to be shortened because the requested LeafTTL would have run
past the root's expiry. In practice that means the root has less than one leaf lifetime
left — by default, less than 90 days. It repeats on every mint from then on.
The fix is to renew the root: Uninstall with Purge(), delete the cached leaf files,
then provision again. See what Purge leaves behind.
What is deliberately not logged¶
- The private key, and any part of it.
- The certificate contents. Only the Common Name and the root's expiry appear in log attributes.
- The trust-store commands and their output.
sudo,certutilandsecuritywrite their own messages to the terminal directly;localcadoes not capture or re-emit them, which is why a failing install can print output that does not appear in your structured logs.