holger error codes — holger-<subsystem>-<n>
FROZEN. APPEND-ONLY. NEVER REUSED.
The machine half of every non-UI error holger emits. Each error carries two channels in one message — a visible human string AND this stable code:
[holger-update-22] sequence rollback: bundle sequence 7 is not newer than the accepted 9
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
machine channel human channel (the typed error's own safe, path-free message)
Why it matters here
holger is a secure artifact server. The Secure Update Gateway's refusals are trust verdicts: an operator (and an automated importer) must be able to tell "your signature is invalid" from "this bundle is a replay" from "the disk is full". Collapsed into one opaque "rejected", those three demand three different responses and get one. The code makes the verdict machine-checkable while the prose keeps it readable.
The law
- FROZEN — a published code never changes meaning. Reword a summary freely; never re-point a code at a different failure.
- APPEND-ONLY — retire a code by leaving it in the registry and ceasing to emit it. NEVER reuse the number: a retired code in an old audit row must stay unambiguous.
- UNIQUE within its subsystem and globally across the app.
- Consumers may prepend a mount prefix; the parser finds the bracketed code anywhere in the string.
- WIRED or RESERVED, and the claim is guarded. Every row declares whether it is raised today (
wired) or merely claimed (reserved), plus the file it is raised in.errcode/tests/wiring_guard.rschecks that against the real source tree in BOTH directions.
wired vs reserved — why the split exists
A registry that merely LISTS codes will happily claim coverage it does not have, and holger shipped exactly that. For four sessions the registry declared 65 codes while 0 of the 38 tonic::Status construction sites — the only surface a remote client ever sees — carried one. Nothing failed, because nothing checked. The declaration was green; the wire raised nothing.
wired— raised at a real error site in the row'ssrcfile. Drop the code from that site and the guard FAILS, naming the code and the file.reserved— the number is claimed, frozen and unique so it can never be handed to a different failure later, but no site raises it yet. If a reserved code turns out to BE raised, the guard fails the other way and the row must be promoted.
The second direction is what stops the split degenerating into "mark everything reserved and the guard goes quiet".
The honest number
The count is the headline of the registry section below. Its tables, its counts and each subsystem's next free ordinal are generated from holger_errcode::ALL (the codes! table) by errcode/tests/registry_doc_is_current.rs, which fails while this file and the registry disagree (HOL-DOCFIND, 2026-11-01: the hand-written count said 116 codes in 9 subsystems while the registry held 332 in 42). Regenerate after a registry change:
HOLGER_ERRCODES_REGEN=1 cargo test -p holger-errcode --test registry_doc_is_current
The headings and the prose under each heading are written by hand and kept by the generator. cargo test -p holger-errcode --test wiring_guard is what proves the wired/reserved split honest.
The reserved rows are reserved for stated reasons, not by neglect:
| subsystem | reserved | why it cannot be wired yet |
marketplace |
14 | the marketplace doors were cut in 9521bf0; the codes stay frozen and nothing raises them. |
storage |
5 | RepositoryBackendTrait returns anyhow::Error; the gRPC door launders every backend failure into holger-server-4 so a read path cannot leak an archive path. Wiring these needs a typed backend error first. |
update |
3 | BundleError has no Import/Scrub/Backup variant; those failure branches do not exist. |
jobs |
3 | numbers claimed for the background job runner's own refusals; the guard's PLANNED_FILES allowlist names the file they are earmarked for. |
audit |
3 | audit-5..7 (an unlinked segment, a pinned tail that differs, an unchained segment) are claimed for holger-server audit verify; nothing raises them by these names yet. |
auth |
2 | validate_request (now edda's nornir-auth-policy) collapses every credential failure into one AuthError, so holger cannot yet tell an expired token from an absent one; and the boot-time warn_* checks log rather than refuse. |
twin |
1 | twin-6 (a recorded role that the environment's role parameter contradicts) has no site that raises it. |
The gRPC wire contract
Every refusal on holger's network surface is built by one function — grpc::coded(&ErrCode, tonic::Code, detail) in server/lib/src/grpc.rs, or by one of its two siblings there: internal_err(e) (a backend failure: the detail goes to the log, the client gets holger-server-4 and "internal error") and refusal(code, why) (a reason worded by the module that decided it: a reason that carries a registry code goes out verbatim with that code on the metadata too, and a reason that carries no code is backend text and is handled as internal_err). grpc.rs holds the only Status::new; the census test grpc::tests::no_service_builds_a_raw_status fails on any other Status::<ctor>( or map_err(Status::..) in server/lib/src (lane C3, 2026-10-20: 46 raw sites at the recount, all routed). So a site cannot drift into a different shape and the two channels can never disagree:
| channel | where | what a client does with it |
| 1 | the Status message, bracketed: [holger-server-1] Repository 'x' not found |
a client that only logs status.message() still records the code |
| 2 | the Status metadata, key x-holger-code (holger_errcode::WIRE_CODE_KEY) |
a client reacts to the exact verdict structurally, without parsing prose |
This is the same shape nornir (7b7357a), korp (status_from_tagged) and dwarves (DwarvesError::to_status) use — one suite convention, not four.
Why it matters more than a tonic code: holger-server-1 ("no such repository") and holger-server-2 ("no such artifact") are BOTH tonic::Code::NotFound. The holger code is the only thing that separates them, and a client that must retry one and not the other needs that difference.
Where it lives
errcode/ — a leaf crate with ZERO dependencies, deliberately: the Secure Update Gateway core (update-bundle) is network-free and self-contained, and the registry has to be usable from there and from server/lib while remaining the ONE place codes are allocated. That is what makes a single global uniqueness gate possible.
Codes are declared through the codes! macro, which enrols each one into holger_errcode::ALL in the same breath — a code cannot enter the app without entering the uniqueness gate.
How a typed error gets its code
Every one of holger's error enums carries a code() whose match is exhaustive on purpose — adding a variant without allocating it a code is a COMPILE error, not a runtime surprise:
| enum | file | codes |
BundleError |
update-bundle/src/error.rs |
holger-update-1..37 (31–33 reserved) |
PromoteError |
server/lib/src/promote/mod.rs |
holger-promote-1..3 (delegates Ladder to the inner error, so the rung verdict survives the wrapping) |
LadderError |
server/lib/src/promote/stages.rs |
holger-promote-4..6 |
| (no enum — raised directly) | server/cli/src/main.rs run_promote |
holger-promote-7 (source artifact absent; the local CLI twin of the RPC's not_found) |
AuditError |
server/lib/src/audit/mod.rs |
holger-audit-1..5 (4/5 are the tamper verdicts: a broken record link, a segment that links to nothing) |
| (no enum — the CLI verb) | server/cli/src/secure_update.rs audit_verify |
holger-audit-6..7 (the operator-pinned chain tail; a segment with no chain at all) |
MarketplaceError |
server/lib/src/marketplace/mod.rs |
holger-marketplace-1..14 (its Display renders both channels; the HTTP door also puts the bare code in the JSON code field and in the console redirect's ?error=) |
| (no enum — the gRPC doors) | server/lib/src/grpc.rs |
holger-auth-1..2, holger-server-1, -4, -6 |
| (no enum — the gRPC handlers) | server/lib/src/grpc/services.rs |
holger-server-2, -3, -7..10, holger-promote-8 |
err.tagged() renders both channels; holger_errcode::parse(&msg) recovers the code.
Gates
| gate | what FAILS it |
holger_errcode::tests::codes_are_unique |
a duplicate code, or a duplicate (subsystem, n) — the test that fails on a repeat |
holger_errcode::tests::code_strings_match_their_parts |
a code string that drifted from its (subsystem, n) |
holger_errcode::tests::parse_does_not_confuse_prefix_codes |
holger-update-1 recovered from a holger-update-10 message |
update_bundle::error::errcode_tests::every_bundle_error_variant_has_a_unique_code |
two BundleError variants sharing a code, or a code missing from the global registry |
update_bundle::error::errcode_tests::the_trust_verdicts_are_distinguishable_by_code |
a rollback, a replay and a bad signature collapsing together |
errcode/tests/wiring_guard.rs::wiring_claims_match_the_real_source_tree |
a wired row nothing raises in its declared file, or a reserved row that IS raised — the guard that makes the coverage number honest. Proven by mutation: reverting get_repo to a bare Status::not_found reports exactly holger-server-1 is marked WIRED but server/lib/src/grpc.rs never references SERVER_REPO_UNKNOWN. |
errcode/tests/wiring_guard.rs::the_grpc_surface_raises_codes_at_all |
the auth or server subsystem going back to zero wired codes — the SK178 state |
server/lib/tests/grpc_error_codes_on_the_wire.rs |
the code not arriving at a REAL remote client. Starts holger over TCP, dials it with the generated tonic client, asserts the received Status's tonic code, its bracketed message AND its x-holger-code metadata — separately, so dropping only the metadata insert still fails (proven: 5 of 6 tests go red, the sixth being the absence control). |
server/lib/tests/marketplace_fulfilment.rs |
a marketplace code not reaching a real HTTP client: asserts holger-marketplace-1 (replayed token, in the console ?error=), -5 (forged operation), -9 (no token), -10 (unknown tenant), -13 (a forged callback, a cancelled sign-in, an exchange without an id_token) and -14 (no / forged webhook bearer) in the door's JSON code field or the console redirect, and -7 on the boot refusal — over the live door, against the mannequin mock + mock Entra |
Run them: cargo test -p holger-errcode -p holger-update-bundle -p holger-server-lib
What these gates do NOT prove
The wire test asserts 5 distinct codes across 2 of the 8 gRPC services, because those are the refusals a client can provoke from a default RON config. The other 33 sites are covered at SOURCE level only (the wiring guard sees the raise; nothing yet proves their Status leaves the process). Notably holger-server-9 is unreachable from a default config — holger builds a promotion engine by default, so the "capability not configured" branch needs a config that omits one. Closing that gap means a config matrix, not another assertion.
Asserting a code in a test
Assert the code, never a substring of the prose:
assert_eq!(holger_errcode::parse(&e.tagged()), Some(&holger_errcode::UPDATE_SEQUENCE_ROLLBACK));
Suite namespaces
holger-<subsystem>-<n> (this app) · nornir-<subsystem>-<n> · korp-<subsystem>-<n> · dwarves-<subsystem>-<n> · facet-<component>-<n> (facett UI).
The registry — 351 codes across 45 subsystems, 320 wired / 31 reserved
status is the row's WIRING CLAIM, not a wish: wired = raised at a real error site in src today; reserved = the number is claimed, frozen and unique, but nothing raises it yet. errcode/tests/wiring_guard.rs checks BOTH directions against the real source tree, so a lying row FAILS the build.
update — the Secure Update Gateway (update-bundle + holger bundle)
40 code(s) — 37 wired, 3 reserved.
| code | const | status | means | src |
holger-update-1 |
UPDATE_SCHEMA_UNSUPPORTED |
wired |
bundle schema version is not supported | update-bundle/src/error.rs |
holger-update-2 |
UPDATE_POLICY_SCHEMA_UNSUPPORTED |
wired |
trust-policy schema version is not supported | update-bundle/src/error.rs |
holger-update-3 |
UPDATE_UNSAFE_PATH |
wired |
unsafe member path rejected | update-bundle/src/error.rs |
holger-update-4 |
UPDATE_LIMIT_EXCEEDED |
wired |
bundle exceeds a resource limit | update-bundle/src/error.rs |
holger-update-5 |
UPDATE_MEMBER_MISSING |
wired |
a manifested bundle member is missing | update-bundle/src/error.rs |
holger-update-6 |
UPDATE_MEMBER_UNREFERENCED |
wired |
bundle contains an unreferenced member | update-bundle/src/error.rs |
holger-update-7 |
UPDATE_DIGEST_MISMATCH |
wired |
member digest mismatch | update-bundle/src/error.rs |
holger-update-8 |
UPDATE_CANDIDATE_DIGEST_MISMATCH |
wired |
candidate digest mismatch — core.json is not what was approved | update-bundle/src/error.rs |
holger-update-9 |
UPDATE_ENVELOPE_MISMATCH |
wired |
envelope is inconsistent with core.json | update-bundle/src/error.rs |
holger-update-10 |
UPDATE_RELEASE_SIGNATURE_MISSING |
wired |
bundle carries no release signature | update-bundle/src/error.rs |
holger-update-11 |
UPDATE_RELEASE_SIGNATURE_INVALID |
wired |
release signature is invalid | update-bundle/src/error.rs |
holger-update-12 |
UPDATE_APPROVAL_SIGNATURE_INVALID |
wired |
an approval signature is invalid | update-bundle/src/error.rs |
holger-update-13 |
UPDATE_UNTRUSTED_SIGNER |
wired |
approval from an untrusted signer | update-bundle/src/error.rs |
holger-update-14 |
UPDATE_UNTRUSTED_RELEASE_SIGNER |
wired |
release signed by an untrusted signer | update-bundle/src/error.rs |
holger-update-15 |
UPDATE_TWO_PERSON_RULE |
wired |
two-person rule unsatisfied | update-bundle/src/error.rs |
holger-update-16 |
UPDATE_ROLE_MISSING |
wired |
a required approval role is missing | update-bundle/src/error.rs |
holger-update-17 |
UPDATE_EXPIRED |
wired |
bundle has expired | update-bundle/src/error.rs |
holger-update-18 |
UPDATE_TOO_OLD |
wired |
bundle is older than the freshness floor | update-bundle/src/error.rs |
holger-update-19 |
UPDATE_EXPIRY_MISSING |
wired |
bundle declares no expiry | update-bundle/src/error.rs |
holger-update-20 |
UPDATE_EVIDENCE_MISSING |
wired |
required evidence is missing | update-bundle/src/error.rs |
holger-update-21 |
UPDATE_TARGET_MISMATCH |
wired |
bundle targets a different installation | update-bundle/src/error.rs |
holger-update-22 |
UPDATE_SEQUENCE_ROLLBACK |
wired |
sequence rollback — bundle is older than what is installed | update-bundle/src/error.rs |
holger-update-23 |
UPDATE_SEQUENCE_REPLAY |
wired |
sequence replay — this bundle was already accepted | update-bundle/src/error.rs |
holger-update-24 |
UPDATE_BUNDLE_ID_REUSE |
wired |
bundle id reuse | update-bundle/src/error.rs |
holger-update-25 |
UPDATE_CERTIFICATE |
wired |
signer certificate is not valid | update-bundle/src/error.rs |
holger-update-26 |
UPDATE_POLICY |
wired |
trust policy is unusable | update-bundle/src/error.rs |
holger-update-27 |
UPDATE_MALFORMED |
wired |
bundle is malformed | update-bundle/src/error.rs |
holger-update-28 |
UPDATE_CONTAINER |
wired |
bundle container could not be read | update-bundle/src/error.rs |
holger-update-29 |
UPDATE_IO |
wired |
bundle IO failed | update-bundle/src/error.rs |
holger-update-30 |
UPDATE_SERDE |
wired |
bundle (de)serialisation failed | update-bundle/src/error.rs |
holger-update-31 |
UPDATE_IMPORT |
reserved |
import into the protected store failed | update-bundle/src/finalize.rs |
holger-update-32 |
UPDATE_SCRUB |
reserved |
scrub of a rejected bundle failed | update-bundle/src/finalize.rs |
holger-update-33 |
UPDATE_BACKUP |
reserved |
backup or restore failed | update-bundle/src/rollback.rs |
holger-update-34 |
UPDATE_TRUST_MODE_UNSET |
wired |
trust policy states no trust mode | update-bundle/src/error.rs |
holger-update-35 |
UPDATE_TRUST_ROOTS_EMPTY |
wired |
rooted-chain trust policy lists no trusted root | update-bundle/src/error.rs |
holger-update-36 |
UPDATE_CERTIFICATE_EXPIRED |
wired |
signer certificate has expired | update-bundle/src/error.rs |
holger-update-37 |
UPDATE_CERTIFICATE_NOT_YET_VALID |
wired |
signer certificate is not yet valid | update-bundle/src/error.rs |
holger-update-38 |
UPDATE_ROLLBACK_FLOOR_ABSENT |
wired |
no anti-rollback floor — refusing without --first-import | update-bundle/src/error.rs |
holger-update-39 |
UPDATE_EXPIRED_POSTURE_UNSET |
wired |
trust policy's expired-metadata posture is not ReadOnly or Refuse | update-bundle/src/error.rs |
holger-update-40 |
UPDATE_VERDICT_NOT_PASS |
wired |
the bundle's recorded policy verdict is not pass | update-bundle/src/error.rs |
Next free ordinal in update: 41
promote — the promotion ladder (server/lib/src/promote/)
10 code(s) — 10 wired, 0 reserved.
| code | const | status | means | src |
holger-promote-1 |
PROMOTE_ALREADY_PROMOTED |
wired |
artifact is already promoted | server/lib/src/promote/mod.rs |
holger-promote-2 |
PROMOTE_POLICY_BLOCKED |
wired |
promotion blocked by policy | server/lib/src/promote/mod.rs |
holger-promote-3 |
PROMOTE_IO |
wired |
promotion IO failed | server/lib/src/promote/mod.rs |
holger-promote-4 |
PROMOTE_UNKNOWN_STAGE |
wired |
no such stage in the ladder | server/lib/src/promote/stages.rs |
holger-promote-5 |
PROMOTE_NOT_FORWARD |
wired |
promotion does not move forward | server/lib/src/promote/stages.rs |
holger-promote-6 |
PROMOTE_SKIPS_STAGES |
wired |
promotion skips mandatory stages | server/lib/src/promote/stages.rs |
holger-promote-7 |
PROMOTE_SOURCE_NOT_FOUND |
wired |
artifact not found in the source repository | server/cli/src/lib.rs |
holger-promote-8 |
PROMOTE_PROPERTY_REQUIRED |
wired |
promotion requires a property the source artifact does not carry | server/lib/src/grpc/services.rs |
holger-promote-9 |
PROMOTE_UNKNOWN_REPOSITORY |
wired |
promotion names a repository this server does not serve | server/lib/src/promote/mod.rs |
holger-promote-10 |
PROMOTE_PROVENANCE_UNVERIFIED |
wired |
an artifact's evidence does not chain to the declared attestation trust root | server/lib/src/promote/gate.rs |
Next free ordinal in promote: 11
intake — the artifact intake chain (server/lib/src/promote/intake.rs)
UNTRUSTED → INGESTED → SCANNED → POLICY_CHECKED → APPROVED → SEALED → PROMOTED → AVAILABLE, with QUARANTINED and BLOCKED as holds. IntakeError::code() maps every refusal.
20 code(s) — 20 wired, 0 reserved.
| code | const | status | means | src |
holger-intake-1 |
INTAKE_SKIPS_STATE |
wired |
the transition skips an intake state | server/lib/src/promote/intake.rs |
holger-intake-2 |
INTAKE_NOT_FORWARD |
wired |
the intake transition does not move forward | server/lib/src/promote/intake.rs |
holger-intake-3 |
INTAKE_TERMINAL |
wired |
the artifact's intake state cannot be left that way | server/lib/src/promote/intake.rs |
holger-intake-4 |
INTAKE_UNKNOWN_STATE |
wired |
no such intake state | server/lib/src/promote/intake.rs |
holger-intake-5 |
INTAKE_NOT_INGESTED |
wired |
the artifact has no intake record | server/lib/src/promote/intake.rs |
holger-intake-6 |
INTAKE_POLICY_REFUSED |
wired |
the intake transition's policy refused | server/lib/src/promote/intake.rs |
holger-intake-7 |
INTAKE_EVIDENCE_MISSING |
wired |
the intake transition lacks required evidence | server/lib/src/promote/intake.rs |
holger-intake-8 |
INTAKE_AUDIT_FAILED |
wired |
the intake transition's audit record could not be written | server/lib/src/promote/intake.rs |
holger-intake-9 |
INTAKE_INTEGRITY |
wired |
the artifact's bytes do not match the ingested digest | server/lib/src/promote/intake.rs |
holger-intake-10 |
INTAKE_IMMUTABLE |
wired |
a sealed coordinate cannot be ingested again | server/lib/src/promote/intake.rs |
holger-intake-11 |
INTAKE_DOOR_REFUSED |
wired |
this repository is fed only by the intake chain | server/lib/src/promote/intake.rs |
holger-intake-12 |
INTAKE_NO_COORDINATE |
wired |
the upload names no artifact coordinate | server/lib/src/promote/intake.rs |
holger-intake-13 |
INTAKE_STORE |
wired |
the intake chain's storage failed | server/lib/src/promote/intake.rs |
holger-intake-14 |
INTAKE_QUARANTINE_PROPERTY_RETIRED |
wired |
the retired quarantine property is still set; the intake QUARANTINED hold replaces it | server/lib/src/lib.rs |
holger-intake-15 |
INTAKE_SIDE_DOOR |
wired |
this repository is outside the intake chain and the policy requires a scan: a write here would be served unscanned | server/lib/src/promote/intake.rs |
holger-intake-16 |
INTAKE_UNSCANNED_REFUSED |
wired |
an unscanned repository is declared where the policy requires a scan | server/lib/src/lib.rs |
holger-intake-17 |
INTAKE_UNSCANNED_UPSTREAM |
wired |
an upstream proxy would serve bytes the intake chain never scanned | server/lib/src/lib.rs |
holger-intake-18 |
INTAKE_CHAIN_REQUIRED |
wired |
a Critical Holger with a writable or proxy repository declares no intake chain | server/lib/src/lib.rs |
holger-intake-19 |
INTAKE_GROUP_MEMBER_REFUSED |
wired |
a group would serve a member raw, past the chain or the member's own gate | server/lib/src/lib.rs |
holger-intake-20 |
INTAKE_RAW_IMPORT_REFUSED |
wired |
a bulk import would land bytes raw, past the intake chain | server/lib/src/grpc/migration.rs |
Next free ordinal in intake: 21
npm — the npm door of the intake chain (server/lib/src/promote/npm.rs, lane P5)
5 code(s) — 5 wired, 0 reserved.
| code | const | status | means | src |
holger-npm-1 |
NPM_PUBLISH_INVALID |
wired |
not an npm publish of one version with its tarball | server/lib/src/promote/npm.rs |
holger-npm-2 |
NPM_TARBALL_MISMATCH |
wired |
the published tarball is not what its document says | server/lib/src/promote/npm.rs |
holger-npm-3 |
NPM_REWRITE_REFUSED |
wired |
published npm versions are never unpublished or rewritten | server/lib/src/promote/npm.rs |
holger-npm-4 |
NPM_TAG_REFUSED |
wired |
this npm dist-tag change is refused | server/lib/src/promote/npm.rs |
holger-npm-5 |
NPM_DOOR_CONFIG |
wired |
the npm door of the intake chain is not declared consistently | server/lib/src/lib.rs |
Next free ordinal in npm: 6
cargo — the cargo door of the intake chain (server/lib/src/promote/cargo.rs, lane HOL-CARGO-PUBLISH-DOOR)
4 code(s) — 4 wired, 0 reserved.
| code | const | status | means | src |
holger-cargo-1 |
CARGO_PUBLISH_INVALID |
wired |
not a cargo publish of one crate | server/lib/src/promote/cargo.rs |
holger-cargo-2 |
CARGO_CRATE_MISMATCH |
wired |
the published crate is not what its publish says | server/lib/src/promote/cargo.rs |
holger-cargo-3 |
CARGO_YANK_REFUSED |
wired |
this yank or unyank is refused | server/lib/src/promote/cargo.rs |
holger-cargo-4 |
CARGO_DOOR_CONFIG |
wired |
the cargo door of the intake chain is not declared consistently | server/lib/src/lib.rs |
Next free ordinal in cargo: 5
bundles — the bundles door of the intake chain (server/lib/src/import_door.rs, lane HOL-BUNDLES-DOOR)
2 code(s) — 2 wired, 0 reserved.
| code | const | status | means | src |
holger-bundles-1 |
BUNDLES_REFUSED |
wired |
this is not a signed Holger bundle that verifies against the bundles door's trust policy | server/lib/src/import_door.rs |
holger-bundles-2 |
BUNDLES_DOOR_CONFIG |
wired |
the bundles door of the intake chain is not declared consistently | server/lib/src/lib.rs |
Next free ordinal in bundles: 3
oci — scanned pushes into a writable oci registry (server/lib/src/promote/oci_push.rs, lane HOL-OCI-EVIDENCE)
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-oci-1 |
OCI_PUSH_SCAN_REQUIRED |
wired |
this registry's pushes must be scanned: the policy requires a scan | server/lib/src/promote/oci_push.rs |
holger-oci-2 |
OCI_PUSH_RULE_UNKNOWN |
wired |
the scanned registries are not declared consistently | server/lib/src/promote/oci_push.rs |
holger-oci-3 |
OCI_PUSH_DELETE_REFUSED |
wired |
a scanned registry never deletes or rewrites what was pushed | server/lib/src/promote/oci_push.rs |
Next free ordinal in oci: 4
duty — separation of duties on the intake chain (server/lib/src/promote/duties.rs)
Developer, Importer, SecurityApprover, RepositoryAdmin and Auditor are duties of the auth block (edda nornir-auth-policy::Duty). The importer never approves; APPROVED needs promotion.intake.approvals distinct approvers; every approval is an attested statement in the approval evidence slot. DutyError::code() maps every refusal.
7 code(s) — 7 wired, 0 reserved.
| code | const | status | means | src |
holger-duty-1 |
DUTY_IMPORTER_CANNOT_APPROVE |
wired |
the importer of an artifact cannot approve or release it | server/lib/src/promote/duties.rs |
holger-duty-2 |
DUTY_NOT_PERMITTED |
wired |
the caller's duties do not permit this intake verb | server/lib/src/promote/duties.rs |
holger-duty-3 |
DUTY_DUPLICATE_APPROVER |
wired |
this principal already approved this artifact | server/lib/src/promote/duties.rs |
holger-duty-4 |
DUTY_QUORUM_PENDING |
wired |
the approval quorum is not reached yet | server/lib/src/promote/duties.rs |
holger-duty-5 |
DUTY_ANONYMOUS_APPROVER |
wired |
an approval needs an authenticated principal | server/lib/src/promote/duties.rs |
holger-duty-6 |
DUTY_NOT_AVAILABLE |
wired |
a Developer reads only AVAILABLE artifacts | server/lib/src/promote/duties.rs |
holger-duty-7 |
DUTY_FORGED_APPROVAL |
wired |
approval evidence is minted by the server, never supplied | server/lib/src/promote/duties.rs |
Next free ordinal in duty: 8
model — AI model files on the intake chain (server/lib/src/scanner/model.rs)
GGUF, Safetensors and ONNX are first-class model artifacts in a raw repository: the holger-model scanner (slot model) tells each by its content, checks its header and records the architecture, parameter count, tensor count, dtypes and quantization as evidence and as model.* properties. The pickle family (pkl, pickle, pt, pth, joblib, and PyTorch zip checkpoints that hold data.pkl) is blocked by default; models.allow_pickle: ["repo"] turns the block into a warning for the repositories it names.
8 code(s) — 8 wired, 0 reserved.
| code | const | status | means | src |
holger-model-1 |
MODEL_PICKLE_BLOCKED |
wired |
a pickle-family model file runs code when it is loaded, so it is blocked | server/lib/src/scanner/model.rs |
holger-model-2 |
MODEL_TORCH_ZIP_BLOCKED |
wired |
a PyTorch zip checkpoint holds a pickle (data.pkl), so it is blocked | server/lib/src/scanner/model.rs |
holger-model-3 |
MODEL_HEADER_MALFORMED |
wired |
the model file's header is malformed | server/lib/src/scanner/model.rs |
holger-model-4 |
MODEL_TENSOR_OUT_OF_BOUNDS |
wired |
a tensor's data lies outside the file | server/lib/src/scanner/model.rs |
holger-model-5 |
MODEL_TENSOR_OVERLAP |
wired |
two tensors overlap in the file | server/lib/src/scanner/model.rs |
holger-model-6 |
MODEL_FORMAT_MISMATCH |
wired |
the file's name claims a model format its content is not | server/lib/src/scanner/model.rs |
holger-model-7 |
MODEL_PICKLE_ALLOWED |
wired |
a pickle-family model file is allowed in this repository, with a warning | server/lib/src/scanner/model.rs |
holger-model-8 |
MODEL_ALLOW_UNKNOWN_REPO |
wired |
models.allow_pickle names a repository the config does not declare | server/lib/src/scanner/model.rs |
Next free ordinal in model: 9
audit — the append-only audit log (server/lib/src/audit/)
1..3 are the WRITE failures (the append did not happen). 4..7 are the TAMPER-EVIDENCE verdicts, added when the log stopped being append-only by convention only: every record now carries a blake3 link digest over its own fields and its predecessor's digest, and each segment is seeded from the previous segment's tail. An operator must be able to tell "the disk failed" from "a row was rewritten" from "a whole segment is gone" — they demand three different responses.
13 code(s) — 10 wired, 3 reserved.
| code | const | status | means | src |
holger-audit-1 |
AUDIT_IO |
wired |
audit log write failed | server/lib/src/audit/mod.rs |
holger-audit-2 |
AUDIT_ARROW |
wired |
audit log Arrow encoding failed | server/lib/src/audit/mod.rs |
holger-audit-3 |
AUDIT_OTHER |
wired |
audit log failed | server/lib/src/audit/mod.rs |
holger-audit-4 |
AUDIT_CHAIN_BROKEN |
wired |
audit chain broken — a record was altered, inserted or removed | server/lib/src/audit/mod.rs |
holger-audit-5 |
AUDIT_SEGMENT_UNLINKED |
reserved |
audit segment links to nothing — a segment is missing | server/lib/src/audit/mod.rs |
holger-audit-6 |
AUDIT_TAIL_MISMATCH |
reserved |
audit chain tail is not the pinned value | server/cli/src/secure_update.rs |
holger-audit-7 |
AUDIT_UNCHAINED_SEGMENT |
reserved |
audit segment carries no chain — integrity unprovable | server/cli/src/secure_update.rs |
holger-audit-8 |
AUDIT_QUERY_UNAVAILABLE |
wired |
audit query unavailable — this server's audit sink keeps no readable records | server/lib/src/grpc/services.rs |
holger-audit-9 |
AUDIT_SIEM_REFUSED |
wired |
a SIEM export sink is misconfigured or not allowed on this side | server/lib/src/audit/siem.rs |
holger-audit-10 |
AUDIT_TRAIL_FORBIDDEN |
wired |
the artifact trail is read by an Auditor or an Admin only | server/lib/src/audit/trail.rs |
holger-audit-11 |
AUDIT_CHECKPOINT_REFUSED |
wired |
a checkpoint that cannot be signed is refused, never written unsigned | server/lib/src/audit/chain.rs |
holger-audit-12 |
AUDIT_DIR_REFUSED |
wired |
the audit directory cannot be opened, so the server does not start | server/lib/src/lib.rs |
holger-audit-13 |
AUDIT_OFF_REFUSED |
wired |
the config turns the audit log off, and no Holger runs without its audit log | server/lib/src/lib.rs |
Next free ordinal in audit: 14
auth — authentication + RBAC, raised at the gRPC doors
6 code(s) — 4 wired, 2 reserved.
| code | const | status | means | src |
holger-auth-1 |
AUTH_UNAUTHENTICATED |
wired |
request carried no usable credential | server/lib/src/grpc.rs |
holger-auth-2 |
AUTH_PERMISSION_DENIED |
wired |
identity is not permitted this resource | server/lib/src/grpc.rs |
holger-auth-3 |
AUTH_CONFIG_BROKEN |
reserved |
auth configuration is unusable — failing closed | server/lib/src/auth.rs |
holger-auth-4 |
AUTH_TOKEN_INVALID |
reserved |
token is expired or malformed | server/lib/src/auth.rs |
holger-auth-5 |
AUTH_FIRST_KEY_ENROLLED |
wired |
the first admin key is already enrolled; the first-key door is shut | server/lib/src/grpc/doors.rs |
holger-auth-6 |
AUTH_INVITE_NEEDS_PERSON |
wired |
an invite that makes an approver needs a person's stepped-up session, never a machine token | server/lib/src/passkey.rs |
Next free ordinal in auth: 7
server — the request surface (server/lib)
14 code(s) — 14 wired, 0 reserved.
| code | const | status | means | src |
holger-server-1 |
SERVER_REPO_UNKNOWN |
wired |
no such repository | server/lib/src/grpc.rs |
holger-server-2 |
SERVER_ARTIFACT_UNKNOWN |
wired |
no such artifact | server/lib/src/grpc/services.rs |
holger-server-3 |
SERVER_BAD_REQUEST |
wired |
malformed request | server/lib/src/grpc/services.rs |
holger-server-4 |
SERVER_INTERNAL |
wired |
request failed internally | server/lib/src/grpc.rs |
holger-server-5 |
SERVER_UNAVAILABLE |
wired |
a backing resource is unavailable | server/lib/src/grpc/services.rs |
holger-server-6 |
SERVER_READ_ONLY |
wired |
server is read-only in this build | server/lib/src/grpc.rs |
holger-server-7 |
SERVER_REPO_READ_ONLY |
wired |
repository is not writable | server/lib/src/grpc/services.rs |
holger-server-8 |
SERVER_PAYLOAD_TOO_LARGE |
wired |
payload exceeds the ingest body cap | server/lib/src/grpc/services.rs |
holger-server-9 |
SERVER_CAPABILITY_NOT_CONFIGURED |
wired |
that capability is not configured on this server | server/lib/src/grpc/services.rs |
holger-server-10 |
SERVER_SBOM_UNKNOWN |
wired |
no SBOM hosted for that coordinate | server/lib/src/grpc/services.rs |
holger-server-11 |
SERVER_READ_BUDGET_EXHAUSTED |
wired |
server is already serving as many artifact bytes as its read budget allows | server/lib/src/grpc.rs |
holger-server-12 |
SERVER_TOO_MANY_CONCURRENT_READS |
wired |
server is already serving as many concurrent reads as it allows | server/lib/src/grpc.rs |
holger-server-13 |
SERVER_ENV_POLICY_REFUSED |
wired |
a security policy was named by the environment; it lives in the RON config | server/lib/src/lib.rs |
holger-server-14 |
SERVER_PATH_NOT_CANONICAL |
wired |
the request path is not canonical (an empty, . or .. segment) |
server/lib/src/exposed/http.rs |
Next free ordinal in server: 15
metered — the paid state (server/lib/src/metered.rs)
7 code(s) — 7 wired, 0 reserved.
| code | const | status | means | src |
holger-metered-1 |
METERED_FACT_MALFORMED |
wired |
entitlement fact is malformed | server/lib/src/metered.rs |
holger-metered-2 |
METERED_CAP_UNPOLICEABLE |
wired |
a cap names a meter holger cannot police per repository | server/lib/src/metered.rs |
holger-metered-3 |
METERED_SIGNATURE_INVALID |
wired |
entitlement signature does not verify | server/lib/src/metered.rs |
holger-metered-4 |
METERED_NOT_CONFIGURED |
wired |
no monetize public key is configured | server/lib/src/metered.rs |
holger-metered-5 |
METERED_UNKNOWN_REPOSITORY |
wired |
entitlement names a repository this server does not serve | server/lib/src/metered.rs |
holger-metered-6 |
METERED_OVER_CAP |
wired |
upload refused: the repository is over its paid disk_bytes limit or its plan is suspended | server/lib/src/grpc/services.rs |
holger-metered-7 |
METERED_PURGE_REFUSED |
wired |
purge refused: the repository is not suspended or in retention | server/lib/src/metered.rs |
Next free ordinal in metered: 8
storage — repositories + object storage (server/repository/*)
5 code(s) — 0 wired, 5 reserved.
| code | const | status | means | src |
holger-storage-1 |
STORAGE_OPEN |
reserved |
cannot open the storage root | server/lib/src/repository.rs |
holger-storage-2 |
STORAGE_READ |
reserved |
storage read failed | server/lib/src/repository.rs |
holger-storage-3 |
STORAGE_WRITE |
reserved |
storage write failed | server/lib/src/repository.rs |
holger-storage-4 |
STORAGE_DIGEST_MISMATCH |
reserved |
stored object digest mismatch | server/lib/src/repository.rs |
holger-storage-5 |
STORAGE_NO_SPACE |
reserved |
storage is out of space | server/lib/src/repository.rs |
Next free ordinal in storage: 6
cli — the thin client holger-cli (holger-cli/, lane B3)
A refusal the server sent keeps the server's own code.
4 code(s) — 4 wired, 0 reserved.
| code | const | status | means | src |
holger-cli-1 |
CLI_INVALID_ARGS |
wired |
invalid command arguments | holger-cli/src/error.rs |
holger-cli-2 |
CLI_PATH_MISSING |
wired |
path argument does not exist | holger-cli/src/error.rs |
holger-cli-3 |
CLI_VERB_UNAVAILABLE |
wired |
verb is not available in this build | holger-cli/src/error.rs |
holger-cli-4 |
CLI_SERVER_UNREACHABLE |
wired |
cannot reach the server | holger-cli/src/error.rs |
Next free ordinal in cli: 5
jobs — the background job runner
3 code(s) — 0 wired, 3 reserved.
| code | const | status | means | src |
holger-jobs-1 |
JOBS_FAILED |
reserved |
job failed | holger-jobs/src/lib.rs |
holger-jobs-2 |
JOBS_STORE |
reserved |
job store failed | holger-jobs/src/lib.rs |
holger-jobs-3 |
JOBS_TIMEOUT |
reserved |
job exceeded its deadline | holger-jobs/src/lib.rs |
Next free ordinal in jobs: 4
marketplace — cloud-marketplace fulfilment (server/lib/src/marketplace/)
Trust verdicts on an unauthenticated, mutating door (/-/marketplace/landing, /-/marketplace/callback, /-/marketplace/webhook), so every refusal must be distinguishable in the audit row: "the marketplace rejected your token" is not "you are rate-limited" is not "we never sold that plan" is not "you signed in from the wrong directory". Raised by MarketplaceError::code; the HTTP door answers the mapped status, puts the bare code in the JSON body's code field, and sends a browser to the console with ?error=<code>. A caller sees the code and its frozen summary only (MarketplaceError::public_message); the detail stays in the audit row and the server log. The marketplace doors were cut in 9521bf0; the codes stay frozen.
14 code(s) — 0 wired, 14 reserved.
| code | const | status | means | src |
holger-marketplace-1 |
MARKETPLACE_TOKEN_REJECTED |
reserved |
purchase token was not accepted by the marketplace | server/lib/src/lib.rs |
holger-marketplace-2 |
MARKETPLACE_PLAN_UNKNOWN |
reserved |
subscription names a plan this server does not offer | server/lib/src/lib.rs |
holger-marketplace-3 |
MARKETPLACE_SUBSCRIPTION_ID_UNSAFE |
reserved |
subscription id is not a safe tenant name | server/lib/src/lib.rs |
holger-marketplace-4 |
MARKETPLACE_PROVISION_IO |
reserved |
tenant provisioning failed on disk | server/lib/src/lib.rs |
holger-marketplace-5 |
MARKETPLACE_OPERATION_UNVERIFIED |
reserved |
webhook operation could not be verified against the marketplace | server/lib/src/lib.rs |
holger-marketplace-6 |
MARKETPLACE_RATE_LIMITED |
reserved |
too many fulfilment attempts from this source | server/lib/src/lib.rs |
holger-marketplace-7 |
MARKETPLACE_NOT_CONFIGURED |
reserved |
marketplace is configured but cannot be served — missing or refused publisher credentials, an unprovisionable plan, or a build without outbound HTTP / OIDC | server/lib/src/lib.rs |
holger-marketplace-8 |
MARKETPLACE_UPSTREAM |
reserved |
marketplace fulfilment API call failed | server/lib/src/lib.rs |
holger-marketplace-9 |
MARKETPLACE_BAD_REQUEST |
reserved |
malformed fulfilment request | server/lib/src/lib.rs |
holger-marketplace-10 |
MARKETPLACE_TENANT_UNKNOWN |
reserved |
no provisioned tenant for this subscription | server/lib/src/lib.rs |
holger-marketplace-11 |
MARKETPLACE_BENEFICIARY_UNKNOWN |
reserved |
subscription names no buyer directory — refusing to provision an open tenant | server/lib/src/lib.rs |
holger-marketplace-12 |
MARKETPLACE_SUBSCRIPTION_NOT_ACTIVATABLE |
reserved |
subscription is not in an activatable state | server/lib/src/lib.rs |
holger-marketplace-13 |
MARKETPLACE_SIGN_IN_REQUIRED |
reserved |
buyer sign-in missing, unverifiable, or from a different directory than the purchase | server/lib/src/lib.rs |
holger-marketplace-14 |
MARKETPLACE_WEBHOOK_UNAUTHENTICATED |
reserved |
webhook carried no valid marketplace bearer token | server/lib/src/lib.rs |
Next free ordinal in marketplace: 15
front — holger.rs's public front page (holger-front/)
5 code(s) — 5 wired, 0 reserved.
| code | const | status | means | src |
holger-front-1 |
FRONT_METHOD_NOT_ALLOWED |
wired |
the front door answers GET and HEAD only | holger-front/src/lib.rs |
holger-front-2 |
FRONT_NO_BROWSER_LOGIN |
wired |
this server offers no browser login | holger-front/src/lib.rs |
holger-front-3 |
FRONT_READS_GATED |
wired |
reads are gated, so the front page cannot name itself | holger-front/src/lib.rs |
holger-front-4 |
FRONT_DOOR_ABSENT |
wired |
this build of holger-server has no front door | holger-front/src/lib.rs |
holger-front-5 |
FRONT_REPORT_REFUSED |
wired |
the estate front's report is not kept: its proof, its age or its front is refused | server/lib/src/front_report.rs |
Next free ordinal in front: 6
attest — the attestation evidence plane (server/lib/src/attest.rs)
An attestation is a signed statement ABOUT SPECIFIC BYTES. These are deliberately not one "attestation rejected" code: the answers demand different actions — re-sign, re-run the gate against the right artifact, enrol the gate's key, teach the server the predicate, fix the producer's JSON, or fix the trust root itself.
★ attest-3 is the load-bearing one. A DSSE envelope that verifies perfectly but whose in-toto subject[].digest names DIFFERENT bytes is a genuine signature over somebody else's artifact.
★ attest-10 and attest-11 are W17's (2026-09-21). Before them, an unreadable declared trust root was an attest-8 store-I/O error at best and, for an empty or non-DER file, no error at all: from_der_root_files pushed the bytes and the estate verified against fewer roots than it had declared while the boot log said the evidence plane was mounted.
11 code(s) — 11 wired, 0 reserved.
| code | const | status | means | src |
holger-attest-1 |
ATTEST_ENVELOPE_MALFORMED |
wired |
DSSE envelope is malformed | server/lib/src/attest.rs |
holger-attest-2 |
ATTEST_STATEMENT_MALFORMED |
wired |
payload is not an in-toto Statement v1 with a digested subject | server/lib/src/attest.rs |
holger-attest-3 |
ATTEST_SUBJECT_MISMATCH |
wired |
statement's subject digests do not name the artifact being attested | server/lib/src/attest.rs |
holger-attest-4 |
ATTEST_SIGNER_UNTRUSTED |
wired |
no enrolled gate certificate for this envelope signature | server/lib/src/attest.rs |
holger-attest-5 |
ATTEST_ENVELOPE_UNVERIFIED |
wired |
DSSE signature did not verify or the signer does not chain to a trusted root | server/lib/src/attest.rs |
holger-attest-6 |
ATTEST_PREDICATE_UNSUPPORTED |
wired |
statement declares a predicateType this server does not accept | server/lib/src/attest.rs |
holger-attest-7 |
ATTEST_DIGEST_UNSAFE |
wired |
artifact digest is not a lowercase-hex digest of the declared algorithm | server/lib/src/attest.rs |
holger-attest-8 |
ATTEST_STORE_IO |
wired |
attestation store I/O failed | server/lib/src/attest.rs |
holger-attest-9 |
ATTEST_VERIFICATION_UNAVAILABLE |
wired |
this build cannot verify DSSE envelopes (built without the sign feature) |
server/lib/src/attest.rs |
holger-attest-10 |
ATTEST_TRUST_ROOT_UNREADABLE |
wired |
a declared attestation trust root could not be read, is empty, or is not a DER certificate | server/lib/src/attest.rs |
holger-attest-11 |
ATTEST_NO_TRUST_ROOT_DECLARED |
wired |
promotion provenance was demanded and this server declares no attestation trust root to chain evidence to | server/lib/src/promote/gate.rs |
Next free ordinal in attest: 12
plugin — the WASM package-handler host (plugin/host/)
A loaded .wasm is untrusted code running inside the server process. Before these codes the host had Engine::default() and no resource bounds at all — a module could spin forever and hang the request thread, or grow its linear memory until the host OOM'd — and it loaded any file in ron_plugin_dir with no provenance check whatsoever.
Every bound is a NAMED refusal, never a silent kill, because the operator's next move differs per verdict: a runaway handler gets thrown out, a handler that is merely too big for its ceiling gets a bigger ceiling, and a module that fails verification means the plugin directory is not what the operator thinks it is. The limits also fail safe: PluginLimits::default() is bounded, so a missing config is the strict answer, and a configured 0 is refused (holger-plugin-5) rather than read as "unlimited".
plugin-6..9 are the provenance half. A module that fails verification is a ScanError::UntrustedModule — a BOOT error — never a catalog that quietly holds one handler fewer, which is the same rule registry.rs already applies to a missing plugin directory.
13 code(s) — 13 wired, 0 reserved.
| code | const | status | means | src |
holger-plugin-1 |
PLUGIN_FUEL_EXHAUSTED |
wired |
wasm package handler exhausted its CPU fuel allowance | plugin/host/src/named.rs |
holger-plugin-2 |
PLUGIN_DEADLINE_EXCEEDED |
wired |
wasm package handler exceeded its wall-clock call deadline | plugin/host/src/named.rs |
holger-plugin-3 |
PLUGIN_MEMORY_LIMIT |
wired |
wasm package handler exceeded its linear-memory ceiling | plugin/host/src/named.rs |
holger-plugin-4 |
PLUGIN_TABLE_LIMIT |
wired |
wasm package handler exceeded its table-element ceiling | plugin/host/src/named.rs |
holger-plugin-5 |
PLUGIN_LIMIT_MISCONFIGURED |
wired |
a wasm package-handler limit is zero, which is a misconfiguration and never means unlimited | plugin/host/src/named.rs |
holger-plugin-6 |
PLUGIN_MODULE_UNSIGNED |
wired |
wasm package handler carries no signature and trust roots are configured | plugin/host/src/named.rs |
holger-plugin-7 |
PLUGIN_SIGNATURE_INVALID |
wired |
wasm package handler signature did not verify or the signer is not trusted | plugin/host/src/named.rs |
holger-plugin-8 |
PLUGIN_TRUST_ROOTS_UNREADABLE |
wired |
a wasm package-handler trusted root could not be read or parsed | plugin/host/src/named.rs |
holger-plugin-9 |
PLUGIN_VERIFICATION_UNAVAILABLE |
wired |
this build cannot verify wasm package handlers (built without the verify-modules feature) |
plugin/host/src/named.rs |
holger-plugin-10 |
PLUGIN_BELOW_FLOOR |
wired |
wasm module version is below the anti-rollback floor activated on this box | plugin/host/src/floor.rs |
holger-plugin-11 |
PLUGIN_FLOOR_UNREADABLE |
wired |
the anti-rollback floor file for this module could not be read or parsed | plugin/host/src/floor.rs |
holger-plugin-12 |
PLUGIN_IDENTITY_MISSING |
wired |
wasm module declares no orderable (supplier, product, version), so the anti-rollback floor cannot place it | plugin/host/src/floor.rs |
holger-plugin-13 |
PLUGIN_TRUST_ROOT_UNCONFIGURED |
wired |
this build loads meter guests and no plugin trust root is configured, so no module in the plugin directory loads | server/lib/src/lib.rs |
Next free ordinal in plugin: 14
mvp — the MVP line's OWN refusals (stinky 1.4, 2026-09-21)
1 code(s) — 1 wired, 0 reserved.
| code | const | status | means | src |
holger-mvp-1 |
MVP_FORMAT_NOT_COMPILED |
wired |
repository declares a format this build did not compile (its fmt-* feature is off) | server/lib/src/repository.rs |
Next free ordinal in mvp: 2
twin — the FOLLOWER role (plan §3 W9, stinky 02 §4.1/§6 S2-3)
22 code(s) — 21 wired, 1 reserved.
| code | const | status | means | src |
holger-twin-1 |
TWIN_REFUSES_WRITES |
wired |
this server is a twin and accepts no writes — write to the primary it follows | server/lib/src/grpc.rs |
holger-twin-2 |
TWIN_STORE_TOO_SMALL |
wired |
the twin has less available space than the primary has used — a promotion could not hold the data | server/lib/src/twin.rs |
holger-twin-3 |
TWIN_ESTATE_INCOMPLETE |
wired |
the primary's data root holds items the twin's replication does not cover | server/lib/src/replication.rs |
holger-twin-4 |
TWIN_ROLE_ALREADY_ELECTED |
wired |
this box has already been elected a role and a role is never re-evaluated | server/lib/src/twin.rs |
holger-twin-5 |
TWIN_BOX_NOT_FRESH |
wired |
only a FRESH box may be elected a twin — this one already holds state | server/lib/src/twin.rs |
holger-twin-6 |
TWIN_ROLE_CONFLICT |
reserved |
the recorded role and the environment's role parameter disagree | server/lib/src/twin.rs |
holger-twin-7 |
TWIN_NO_REPLICATION_DOOR |
wired |
this box serves no replication door, so it certifies no reader for one | server/lib/src/twin_tls/mtls.rs |
holger-twin-8 |
TWIN_PRINCIPAL_REFUSED |
wired |
this box does not certify that principal for its replication door | server/lib/src/twin_tls/mtls.rs |
holger-twin-9 |
TWIN_CERT_WRONG_KEY |
wired |
the replication certificate is not for the key this box minted | server/lib/src/twin_tls/mtls.rs |
holger-twin-10 |
TWIN_CERT_NOT_FROM_CA |
wired |
the replication certificate does not chain to the CA handed with it | server/lib/src/twin_tls/mtls.rs |
holger-twin-11 |
TWIN_CA_REPOINTED |
wired |
this box already pins a different replication issuer and is never re-pointed | server/lib/src/twin_tls/mtls.rs |
holger-twin-12 |
TWIN_DOOR_REFUSED |
wired |
the replication door refused a peer: no client certificate, or not one its issuer signed | server/lib/src/twin_tls/mtls.rs |
holger-twin-13 |
TWIN_NOT_CERTIFIED |
wired |
this box holds no replication credential and will not follow a non-loopback source in the clear | server/lib/src/twin_tls.rs |
holger-twin-14 |
TWIN_PAIRING_REFUSED |
wired |
a twin pairing step was refused: its input or this box's role does not fit | server/lib/src/twin_tls.rs |
holger-twin-15 |
TWIN_AWAITING_RECHARGE |
wired |
this box is being recharged from its twin and serves nothing until the recharge is whole | server/lib/src/twin.rs |
holger-twin-16 |
TWIN_RECHARGE_REFUSED |
wired |
the recharge was refused before a byte moved: no twin, a main that is not fresh, an empty twin, a twin that cannot give everything back, or a twin whose old primary may still write (not_fenced) | server/lib/src/recharge_lane.rs |
holger-twin-17 |
TWIN_ESTATE_NOT_WG |
wired |
an estate link, door or CA material off the estate's WireGuard tunnel was refused | server/lib/src/tunnel_addr.rs |
holger-twin-18 |
TWIN_CERT_EXPIRED |
wired |
the replication certificate has ended and was not renewed in time | server/lib/src/twin_tls/mtls.rs |
holger-twin-19 |
TWIN_ESTATE_FILE_UNKNOWN |
wired |
the estate file is not held here, or it could not be read | server/lib/src/grpc/estate.rs |
holger-twin-20 |
TWIN_RUNS_NO_JOBS |
wired |
this box is a twin: it runs no job and admits none, it only follows its primary | server/lib/src/jobs.rs |
holger-twin-21 |
TWIN_ROLE_NOT_FROM_PAIRING |
wired |
a role was named by the environment or the config; a role comes only from the pairing's election | server/lib/src/twin.rs |
holger-twin-22 |
TWIN_NOT_FOLLOWED |
wired |
the reclaim waits: the twin has not yet followed what it would drop | server/lib/src/lib.rs |
Next free ordinal in twin: 23
peer — a downstream holger paired with an upstream holger
5 code(s) — 5 wired, 0 reserved.
| code | const | status | means | src |
holger-peer-1 |
PEER_ALREADY_PAIRED |
wired |
this peer is already paired — a pairing is made once and never overwritten | server/lib/src/peers.rs |
holger-peer-2 |
PEER_REPO_NOT_PAIRED |
wired |
this paired downstream is not paired for that repository | server/lib/src/grpc.rs |
holger-peer-3 |
PEER_KEY_MISMATCH |
wired |
the paired upstream presented a different key than the one pinned at pairing | server/lib/src/mirror_cycle.rs |
holger-peer-4 |
PEER_NOT_PAIRED |
wired |
this caller presented no paired downstream certificate, so it may not report a sync point | server/lib/src/peers.rs |
holger-peer-5 |
PEER_NOT_KNOWN |
wired |
a re-pair names a peer that was never paired | server/lib/src/peers.rs |
Next free ordinal in peer: 6
grow — the data set grows WITHOUT a restart (server/lib/src/grow.rs)
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-grow-1 |
GROW_WRITES_HELD |
wired |
uploads are held while holger grows its storage — try again in a few minutes | server/lib/src/grow.rs |
holger-grow-2 |
GROW_STORES_CLOSED |
wired |
the data set is unmounted for a growth — the repository is back when it is | server/lib/src/grow.rs |
holger-grow-3 |
GROW_REFUSED |
wired |
the growth request was refused — the reason is named | server/lib/src/grow.rs |
Next free ordinal in grow: 4
scan — the scanner framework and its evidence store (server/lib/src/scanner/)
Every artifact's scan evidence is kept by its SHA-256, append-only and audited, and signed as an attestation. A record that could not be stored, audited or signed is a refusal. ScanError::code() maps every refusal.
5 code(s) — 5 wired, 0 reserved.
| code | const | status | means | src |
holger-scan-1 |
SCAN_DIGEST_UNSAFE |
wired |
scan evidence names no lowercase-hex SHA-256 for its artifact | server/lib/src/scanner/store.rs |
holger-scan-2 |
SCAN_STORE_IO |
wired |
the scan evidence store failed | server/lib/src/scanner/store.rs |
holger-scan-3 |
SCAN_AUDIT_FAILED |
wired |
the scan could not be audited, so it is refused | server/lib/src/scanner/store.rs |
holger-scan-4 |
SCAN_EVIDENCE_TAMPERED |
wired |
a stored scan evidence record was changed | server/lib/src/scanner/store.rs |
holger-scan-5 |
SCAN_ATTEST_FAILED |
wired |
the scan evidence could not be signed | server/lib/src/scanner/store.rs |
Next free ordinal in scan: 6
airgap — the signed export of the approved set and its verified import (server/lib/src/promote/airgap.rs)
The export takes AVAILABLE artifacts from production with their evidence, attestations and SBOMs; its verdict is computed from the stored evidence and an artifact without passing evidence is refused by name. The import re-verifies every payload hash and every evidence attestation and lands each artifact AVAILABLE, audit first.
10 code(s) — 10 wired, 0 reserved.
| code | const | status | means | src |
holger-airgap-1 |
AIRGAP_NOT_AVAILABLE |
wired |
the artifact is not AVAILABLE in production, so it is not exported | server/lib/src/promote/airgap.rs |
holger-airgap-2 |
AIRGAP_NO_EVIDENCE |
wired |
the artifact has no stored scan evidence, so it is refused from the export | server/lib/src/promote/airgap.rs |
holger-airgap-3 |
AIRGAP_EVIDENCE_FAILED |
wired |
the artifact's stored evidence does not pass, so it is refused from the export | server/lib/src/promote/airgap.rs |
holger-airgap-4 |
AIRGAP_NOT_ATTESTED |
wired |
the artifact's evidence is not signed, so it is refused from the export | server/lib/src/promote/airgap.rs |
holger-airgap-5 |
AIRGAP_NOT_APPROVED |
wired |
the artifact's intake record holds no approval, so it is refused from the export | server/lib/src/promote/airgap.rs |
holger-airgap-6 |
AIRGAP_NOTHING_TO_EXPORT |
wired |
there is no AVAILABLE artifact to export | server/lib/src/promote/airgap.rs |
holger-airgap-7 |
AIRGAP_INDEX_INVALID |
wired |
the bundle's export index is missing or malformed | server/lib/src/promote/airgap.rs |
holger-airgap-8 |
AIRGAP_PAYLOAD_MISMATCH |
wired |
an imported payload does not match its recorded hash | server/lib/src/promote/airgap.rs |
holger-airgap-9 |
AIRGAP_ATTESTATION_INVALID |
wired |
an evidence attestation in the bundle does not verify | server/lib/src/promote/airgap.rs |
holger-airgap-10 |
AIRGAP_AUDIT_FAILED |
wired |
the airgap export or import could not be audited, so it is refused | server/lib/src/promote/airgap.rs |
Next free ordinal in airgap: 11
offline — network: Offline (server/lib/src/egress.rs)
An offline holger refuses a config that needs the network at boot, and refuses every outbound dial before a socket is opened.
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-offline-1 |
OFFLINE_EGRESS_REFUSED |
wired |
the network call is refused: this holger is offline | server/lib/src/egress.rs |
holger-offline-2 |
OFFLINE_CONFIG_REFUSED |
wired |
the config needs the network and declares network: Offline |
server/lib/src/egress.rs |
holger-offline-3 |
OFFLINE_NO_UPSTREAM |
wired |
a remote repository names no upstream address, and holger falls back to none | server/lib/src/repository.rs |
Next free ordinal in offline: 4
import — the box's import doors (lane W4, server/lib/src/import_door.rs)
11 code(s) — 11 wired, 0 reserved.
| code | const | status | means | src |
holger-import-1 |
IMPORT_RAW_BYPASS_REMOVED |
wired |
a bundle import into a raw repository's data directory bypasses intake, so it is refused | server/lib/src/import_door.rs |
holger-import-2 |
IMPORT_NO_INTAKE |
wired |
this server declares no intake chain (promotion.intake) to land an imported bundle in |
server/lib/src/import_door.rs |
holger-import-3 |
IMPORT_NO_INTEL |
wired |
this server declares no intel: block to import an intel bundle into |
server/lib/src/import_door.rs |
holger-import-4 |
IMPORT_NO_POLICY |
wired |
no trust policy is configured for this import | server/lib/src/import_door.rs |
holger-import-5 |
IMPORT_REFUSED |
wired |
the bundle was refused (verification, anti-rollback floor or audit) and nothing landed | server/lib/src/import_door.rs |
holger-import-6 |
IMPORT_STAGING_FAILED |
wired |
the bundle could not be staged for import | server/lib/src/import_door.rs |
holger-import-7 |
IMPORT_REFRESH_OFF |
wired |
this box does not fetch intel (offline, or a build without the fetcher); nothing was dialled | server/lib/src/import_door.rs |
holger-import-8 |
IMPORT_REFRESH_FAILED |
wired |
the intel refresh could not fetch or read its feeds, and the advisory database is unchanged | server/lib/src/import_door.rs |
holger-import-9 |
IMPORT_FIRST_NOT_AUTHORIZED |
wired |
no admin authorized a first import of this vendor, product and sequence, so an absent floor is not established | server/lib/src/import_door.rs |
holger-import-10 |
IMPORT_FIRST_FLAG_REMOVED |
wired |
a caller's first_import flag or an inbox FIRST-IMPORT marker is refused; the first import is an admin action | server/lib/src/import_door.rs |
holger-import-11 |
IMPORT_FIRST_GRANT_REFUSED |
wired |
the first-import authorization is refused (not an admin, incomplete, a floor already stands, or unaudited) | server/lib/src/import_door.rs |
Next free ordinal in import: 12
admission — the door's fair-share gate (server/lib/src/admission*.rs)
2 code(s) — 2 wired, 0 reserved.
| code | const | status | means | src |
holger-admission-1 |
ADMISSION_REFUSED |
wired |
the door admits no more of this work right now; retry after the named seconds | server/lib/src/admission_grpc.rs |
holger-admission-2 |
ADMISSION_PULL_QUEUED |
wired |
the artifact is being fetched from its upstream; retry after the named seconds | server/lib/src/grpc/services.rs |
Next free ordinal in admission: 3
migration — MigrationService (server/lib/src/grpc/migration.rs)
1 code(s) — 1 wired, 0 reserved.
| code | const | status | means | src |
holger-migration-1 |
MIGRATION_WATCHER_LAGGED |
wired |
the progress watcher fell behind and lost rows; it follows from the current state | server/lib/src/grpc/migration.rs |
Next free ordinal in migration: 2
account — the repositories a person has (server/lib/src/account.rs, lane P4)
holger.account.v1.CreateRepository: an admin makes a private repository. Each refusal names what was asked for; nothing is made on any of them.
7 code(s) — 7 wired, 0 reserved.
| code | const | status | means | src |
holger-account-1 |
ACCOUNT_NAME_REFUSED |
wired |
the name is no repository name: nothing was made | server/lib/src/account.rs |
holger-account-2 |
ACCOUNT_NAME_TAKEN |
wired |
the repository name is taken | server/lib/src/account.rs |
holger-account-3 |
ACCOUNT_FORMAT_REFUSED |
wired |
this server makes no repository of that format | server/lib/src/account.rs |
holger-account-4 |
ACCOUNT_MAKES_NONE |
wired |
this server makes no repository at run time | server/lib/src/account.rs |
holger-account-5 |
ACCOUNT_GRANT_NOT_OWNER |
wired |
only the repository's owner or an admin grants on it | server/lib/src/account.rs |
holger-account-6 |
ACCOUNT_GRANT_UNKNOWN |
wired |
no such owner-only repository or person here | server/lib/src/account.rs |
holger-account-7 |
ACCOUNT_GRANT_ACCESS |
wired |
the access is not read, write or none | server/lib/src/account.rs |
Next free ordinal in account: 8
token — repository tokens for package clients (lane P3)
A repository token is what cargo, pip, npm and mvn carry instead of a passkey (server/lib/src/repo_token.rs, gRPC holger.token.v1.TokenService, CLI holger-server token). A refusal names the token's fault and never another person, another repository or what the token is for; an unknown secret gets the plain 401 a forged one gets.
11 code(s) — 11 wired, 0 reserved.
| code | const | status | means | src |
holger-token-1 |
TOKEN_REVOKED |
wired |
this repository token was revoked | server/lib/src/repo_token.rs |
holger-token-2 |
TOKEN_EXPIRED |
wired |
this repository token has expired | server/lib/src/repo_token.rs |
holger-token-3 |
TOKEN_OWNER_GONE |
wired |
the owner of this repository token holds no enabled passkey | server/lib/src/repo_token.rs |
holger-token-4 |
TOKEN_OUT_OF_SCOPE |
wired |
this repository token is not for this repository | server/lib/src/repo_token.rs |
holger-token-5 |
TOKEN_READ_ONLY |
wired |
this repository token may only read | server/lib/src/repo_token.rs |
holger-token-6 |
TOKEN_MINT_PERSON |
wired |
a repository token is minted by a person signed in with a passkey | server/lib/src/repo_token.rs |
holger-token-7 |
TOKEN_MINT_STEP_UP |
wired |
minting a repository token needs a fresh user-verified login | server/lib/src/repo_token.rs |
holger-token-8 |
TOKEN_MINT_BEYOND_OWNER |
wired |
a repository token cannot grant more than its owner holds | server/lib/src/repo_token.rs |
holger-token-9 |
TOKEN_MINT_INVALID |
wired |
the repository token request is not valid | server/lib/src/repo_token.rs |
holger-token-10 |
TOKEN_NOT_FOUND |
wired |
no such repository token | server/lib/src/repo_token.rs |
holger-token-11 |
TOKEN_STORE |
wired |
the repository token store could not be written | server/lib/src/repo_token.rs |
Next free ordinal in token: 12
provenance — (lane G3a, 2026-10-23): the intake provenance scanner
13 code(s) — 13 wired, 0 reserved.
| code | const | status | means | src |
holger-provenance-1 |
PROVENANCE_MISSING |
wired |
no provenance about these bytes was offered, and the policy requires it | provenance/src/error.rs |
holger-provenance-2 |
PROVENANCE_SUBJECT_MISMATCH |
wired |
the attestation names other bytes than the artifact's sha256 or sha512 | provenance/src/error.rs |
holger-provenance-3 |
PROVENANCE_SIGNATURE_INVALID |
wired |
the signature does not verify over the exact signed bytes | provenance/src/error.rs |
holger-provenance-4 |
PROVENANCE_SIGNER_UNTRUSTED |
wired |
the signer is not an allowed key and does not chain to the pinned Fulcio root | provenance/src/error.rs |
holger-provenance-5 |
PROVENANCE_IDENTITY_MISMATCH |
wired |
the signing certificate's issuer and subject are not an allowed identity | provenance/src/error.rs |
holger-provenance-6 |
PROVENANCE_BUILDER_NOT_ALLOWED |
wired |
the SLSA builder is not an allowed builder | provenance/src/error.rs |
holger-provenance-7 |
PROVENANCE_SLSA_LEVEL_TOO_LOW |
wired |
the provenance is below the minimum SLSA build level | provenance/src/error.rs |
holger-provenance-8 |
PROVENANCE_TLOG_UNVERIFIED |
wired |
the transparency-log entry does not verify against the pinned log | provenance/src/error.rs |
holger-provenance-9 |
PROVENANCE_MALFORMED |
wired |
the attestation material cannot be read | provenance/src/error.rs |
holger-provenance-10 |
PROVENANCE_TRUST_ROOT |
wired |
the pinned Sigstore trust root is missing or does not verify | provenance/src/error.rs |
holger-provenance-11 |
PROVENANCE_POLICY_INVALID |
wired |
the provenance policy is not valid | provenance/src/error.rs |
holger-provenance-12 |
PROVENANCE_CERT_EXPIRED |
wired |
the signing certificate was not valid at the logged signing time | provenance/src/error.rs |
holger-provenance-13 |
PROVENANCE_UNSIGNED |
wired |
nothing signed about these bytes was offered, and the policy requires a signature | provenance/src/error.rs |
Next free ordinal in provenance: 14
sandbox — (lane SANDBOX-SCAN, 2026-10-23): scanning runs in a container
20 code(s) — 20 wired, 0 reserved.
| code | const | status | means | src |
holger-sandbox-1 |
SANDBOX_NO_ENGINE |
wired |
no container engine to scan in; holger refuses to scan | server/sandbox/src/lib.rs |
holger-sandbox-2 |
SANDBOX_TIMEOUT |
wired |
the scan worker ran past its wall clock and was killed | server/sandbox/src/lib.rs |
holger-sandbox-3 |
SANDBOX_KILLED |
wired |
the scan worker was killed by its limits | server/sandbox/src/lib.rs |
holger-sandbox-4 |
SANDBOX_REPORT_TOO_LARGE |
wired |
the scan worker's report is larger than its cap | server/sandbox/src/lib.rs |
holger-sandbox-5 |
SANDBOX_REPORT_INVALID |
wired |
the scan worker's report is not valid | server/sandbox/src/lib.rs |
holger-sandbox-6 |
SANDBOX_OFF_IN_RELEASE |
wired |
sandbox: off is allowed only in a test build |
server/sandbox/src/lib.rs |
holger-sandbox-7 |
SANDBOX_NOT_ROOTLESS |
wired |
the container engine is not rootless | server/sandbox/src/lib.rs |
holger-sandbox-8 |
SANDBOX_IMAGE_MISSING |
wired |
the scan worker image is not on this host | server/sandbox/src/lib.rs |
holger-sandbox-9 |
SANDBOX_WORKER_FAILED |
wired |
the scan worker failed without a report | server/sandbox/src/lib.rs |
holger-sandbox-10 |
SANDBOX_CONFIG |
wired |
the sandbox config is not valid | server/sandbox/src/lib.rs |
holger-sandbox-11 |
SANDBOX_IO |
wired |
the scan job could not be prepared | server/sandbox/src/lib.rs |
holger-sandbox-12 |
SANDBOX_CLAMD_DOWN |
wired |
clamd in its sandbox is not answering; holger refuses to scan | server/sandbox/src/lib.rs |
holger-sandbox-13 |
SANDBOX_NO_PIDS_LIMIT |
wired |
nothing bounds a scan job's processes; holger refuses to scan | server/sandbox/src/lib.rs |
holger-sandbox-14 |
SANDBOX_ROOTFS_DRIFT |
wired |
the laid sandbox differs from the medium; holger refuses to scan | server/sandbox/src/lib.rs |
holger-sandbox-15 |
SANDBOX_CLAMD_NOT_SANDBOXED |
wired |
a real build talks to ClamAV only over the sandboxed clamd's unix socket | server/sandbox/src/lib.rs |
holger-sandbox-16 |
SANDBOX_JOB_UNDECLARED |
wired |
the job wrote an output it did not declare, or one that is not a regular file | jobs/runner/src/collect.rs |
holger-sandbox-17 |
SANDBOX_JOB_ANSWER_INVALID |
wired |
the job's answer is missing or not valid | jobs/runner/src/collect.rs |
holger-sandbox-18 |
SANDBOX_JOB_RESULT_REFUSED |
wired |
the job's signed result is not believed (another key, a changed result, or a result for another job) | jobs/runner/src/accept.rs |
holger-sandbox-19 |
SANDBOX_JOB_OUTPUTS_INVALID |
wired |
the job's outputs are not the ones its signed result lists | jobs/runner/src/accept.rs |
holger-sandbox-20 |
SANDBOX_JOB_RUN_FAILED |
wired |
the job runner could not run the job | server/lib/src/job_runner/mod.rs |
Next free ordinal in sandbox: 21
sync — the sync protocol between an upstream and its downstreams (Holger v2.0 H4)
11 code(s) — 11 wired, 0 reserved.
| code | const | status | means | src |
holger-sync-1 |
SYNC_MALFORMED |
wired |
the sync document is malformed | server/lib/src/sync.rs |
holger-sync-2 |
SYNC_UNTRUSTED_SIGNER |
wired |
the sync document's signer is not trusted here | server/lib/src/sync.rs |
holger-sync-3 |
SYNC_BAD_SIGNATURE |
wired |
the sync document's signature does not verify | server/lib/src/sync.rs |
holger-sync-4 |
SYNC_ROLLBACK |
wired |
the sync manifest is older than the generation applied here (a rollback) | server/lib/src/sync.rs |
holger-sync-5 |
SYNC_UNKNOWN_DOWNSTREAM |
wired |
the ack comes from a downstream this upstream has not enrolled | server/lib/src/sync.rs |
holger-sync-6 |
SYNC_FUTURE_GENERATION |
wired |
the ack names a generation this upstream never issued | server/lib/src/sync.rs |
holger-sync-7 |
SYNC_STATE |
wired |
the sync state could not be kept | server/lib/src/sync.rs |
holger-sync-8 |
SYNC_NOT_CONFIGURED |
wired |
this server does not take part in sync in that role | server/lib/src/sync.rs |
holger-sync-9 |
SYNC_AUDIT_FAILED |
wired |
the sync's audit record could not be written, so nothing changed | server/lib/src/sync.rs |
holger-sync-10 |
SYNC_LINK |
wired |
the upstream could not be reached for the sync | server/lib/src/sync.rs |
holger-sync-11 |
SYNC_DOWNSTREAM_REFUSED |
wired |
the downstream verb is refused: not a live downstream, enrolled twice, or not a WireGuard downstream | server/lib/src/sync/downstreams.rs |
Next free ordinal in sync: 12
downstream — (Holger v2.0 H3, 2026-10-25): the on-prem gateway, --features downstream
5 code(s) — 5 wired, 0 reserved.
| code | const | status | means | src |
holger-downstream-1 |
DOWNSTREAM_CONFIG_REFUSED |
wired |
the config asks a downstream for more than its one upstream Holger | server/downstream/src/lib.rs |
holger-downstream-2 |
DOWNSTREAM_EGRESS_REFUSED |
wired |
the network call is refused: a downstream dials only its upstream Holger | server/lib/src/egress.rs |
holger-downstream-3 |
DOWNSTREAM_NO_UPLOAD |
wired |
a downstream takes no upload; its packages arrive from its upstream, verified | server/lib/src/promote/intake.rs |
holger-downstream-4 |
DOWNSTREAM_NOT_SENT |
wired |
the package is not on this downstream; its upstream has not sent it | server/lib/src/pull_intake/mod.rs |
holger-downstream-5 |
DOWNSTREAM_VIA_REFUSED |
wired |
a downstreams: entry is refused: a bad name, a name twice, or a WireGuard key that is not one |
server/downstream/src/via.rs |
Next free ordinal in downstream: 6
depset — a pull's dependency closure, approved as one set (lane HOL-DEPSET-APPROVE)
4 code(s) — 4 wired, 0 reserved.
| code | const | status | means | src |
holger-depset-1 |
DEPSET_UNKNOWN |
wired |
no dependency set has that id | server/lib/src/pull_intake/depset.rs |
holger-depset-2 |
DEPSET_REFUSED |
wired |
a member of the dependency set is refused, so the set is | server/lib/src/pull_intake/depset.rs |
holger-depset-3 |
DEPSET_HELD |
wired |
the dependency set is held: a member is not resolved or not scanned | server/lib/src/pull_intake/depset.rs |
holger-depset-4 |
DEPSET_STALE |
wired |
the dependency set changed since it was read: the vote names another revision | server/lib/src/pull_intake/depset.rs |
Next free ordinal in depset: 5
boundary — a downstream's one-way boundary (lane HOL-CDS, owner 2026-10-30)
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-boundary-1 |
BOUNDARY_ONE_WAY_REFUSED |
wired |
this Holger is one-way: the config names a way out (mirror, export door, sync receipt or outbound target) | server/lib/src/boundary.rs |
holger-boundary-2 |
BOUNDARY_FETCH_NOT_BUILT |
wired |
boundary: Fetch needs a build with the fetch feature |
server/lib/src/boundary.rs |
holger-boundary-3 |
BOUNDARY_DOMAIN_INVALID |
wired |
the domain: label is not one (1 to 64 printable characters, no control characters) |
server/lib/src/boundary.rs |
Next free ordinal in boundary: 4
export — the upstream's push into the diode folder (lane HOL-CDS)
2 code(s) — 2 wired, 0 reserved.
| code | const | status | means | src |
holger-export-1 |
EXPORT_PUSH_CONFIG_REFUSED |
wired |
the export: block is refused: no push_to folder, an unreadable interval, or no intake chain |
server/lib/src/export_push.rs |
holger-export-2 |
EXPORT_PUSH_FAILED |
wired |
the push could not build, sign or write its bundle, and push_to is unchanged | server/lib/src/export_push.rs |
Next free ordinal in export: 3
listen — the listeners' safe defaults (lane HOL-NCSC, NCSC P1, owner 2026-10-30)
6 code(s) — 6 wired, 0 reserved.
| code | const | status | means | src |
holger-listen-1 |
LISTEN_NO_AUTH |
wired |
a listener that is not loopback needs an authentication method | server/lib/src/lib.rs |
holger-listen-2 |
LISTEN_CLEARTEXT |
wired |
a listener that is not loopback needs TLS, or the endpoint's explicit insecure: true |
server/lib/src/lib.rs |
holger-listen-3 |
LISTEN_WRONG_PLANE |
wired |
this door is served on the endpoint's other listener (the data or the admin plane) | server/lib/src/listen.rs |
holger-listen-4 |
LISTEN_PEER_REFUSED |
wired |
the peer is not in the admin listener's allow-list, so the connection was dropped | server/lib/src/listen.rs |
holger-listen-5 |
LISTEN_ADMIN_REFUSED |
wired |
an admin listener needs a good ron_admin_allow (CIDRs) |
server/lib/src/lib.rs |
holger-listen-6 |
LISTEN_TRUSTED_PROXIES_REFUSED |
wired |
an endpoint's ron_trusted_proxies is not a list of CIDRs |
server/lib/src/lib.rs |
Next free ordinal in listen: 7
tls — the doors' TLS material (lane HOL-NCSC, NCSC P3)
1 code(s) — 1 wired, 0 reserved.
| code | const | status | means | src |
holger-tls-1 |
TLS_CRL_REFUSED |
wired |
the client certificates' CRL is refused: unreadable, not a CRL, not signed by the client CA, or expired | server/lib/src/exposed/tls.rs |
Next free ordinal in tls: 2
sigs — scanner signatures as a signed bundle (lane HOL-NCSC, NCSC P2/P3)
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-sigs-1 |
SIGS_MEMBER_REFUSED |
wired |
the signature bundle carries a member that is no signature file | server/lib/src/import_door.rs |
holger-sigs-2 |
SIGS_INSTALL_FAILED |
wired |
the signature files could not be installed | server/lib/src/import_door.rs |
holger-sigs-3 |
SIGS_NOT_BUILT |
wired |
this build carries no scanners, so it takes no signature bundle | server/lib/src/import_door.rs |
Next free ordinal in sigs: 4
trust — the estate's Sigstore trust root (server/lib/src/sigstore_trust.rs, lane HOL-OCI-EVIDENCE)
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-trust-1 |
TRUST_ROOT_NOT_PINNED |
wired |
the Sigstore trusted root is not the pinned one | server/lib/src/sigstore_trust.rs |
holger-trust-2 |
TRUST_ROOT_SEED_REFUSED |
wired |
the Sigstore trust root could not be seeded or installed | server/lib/src/sigstore_trust.rs |
holger-trust-3 |
TRUST_ROOT_RELOAD_FAILED |
wired |
the imported Sigstore trust root could not be read by the scanners | server/lib/src/import_door.rs |
Next free ordinal in trust: 4
time — the monotone time floor and the signed time token (lane HOL-NCSC, NCSC P3)
3 code(s) — 3 wired, 0 reserved.
| code | const | status | means | src |
holger-time-1 |
TIME_BEHIND_FLOOR |
wired |
the clock reads behind the time floor; the box judges at the floor | server/lib/src/time_floor.rs |
holger-time-2 |
TIME_TOKEN_REFUSED |
wired |
the time token is refused: not a token, no time, or a time that is not its signed created_at | server/lib/src/time_floor.rs |
holger-time-3 |
TIME_FLOOR_UNREADABLE |
wired |
the time floor cannot be read or kept, and a floor that cannot be read is not zero | server/lib/src/time_floor.rs |
Next free ordinal in time: 4
key — a private key file is the process's alone (lane HOL-NCSC, NCSC P3)
2 code(s) — 2 wired, 0 reserved.
| code | const | status | means | src |
holger-key-1 |
KEY_FILE_EXPOSED |
wired |
a private key file is readable by its group or others, or owned by another user | server/lib/src/keyfile.rs |
holger-key-2 |
KEY_HSM_REFUSED |
wired |
the hardware-token (PKCS#11) signer is refused | server/lib/src/lib.rs |
Next free ordinal in key: 3