pub enum ControlError {
Show 32 variants
ManifestParse(Error),
ManifestSerialize(Error),
NoManifestPath,
TrustChangeRequiresRestart,
StateChangeRequiresRestart,
InvalidStateConfig(String),
StateBackendInit(String),
InvalidListenConfig(String),
Io(Error),
IoAt {
path: PathBuf,
source: Error,
},
TrustKey(String),
HostInit(String),
Artifact {
source_ref: String,
reason: String,
},
DigestMismatch {
source_ref: String,
expected: String,
actual: String,
},
Load {
id: String,
err: Error,
},
InvalidFilterConfig {
id: String,
reason: String,
},
UnknownChainFilter(String),
DuplicateFilterId(String),
DuplicateUpstream(String),
EmptyUpstreamAddresses(String),
UpstreamRegistryPoisoned,
InvalidUpstreamLb {
name: String,
reason: String,
},
UnknownRouteUpstream {
path_prefix: String,
upstream: String,
},
UnknownRouteFilter {
path_prefix: String,
filter: String,
},
InvalidRoute {
path_prefix: String,
reason: String,
},
InvalidRouteRateLimit {
path_prefix: String,
reason: String,
},
TlsCert {
host: Option<String>,
path: String,
reason: String,
},
Stek {
path: String,
reason: String,
},
UpstreamTlsCa {
upstream: String,
path: String,
reason: String,
},
UpstreamTlsSni {
upstream: String,
sni: String,
reason: String,
},
UpstreamClientCert {
upstream: String,
path: String,
reason: String,
},
ClientAuthCa {
path: String,
reason: String,
},
}Variants§
ManifestParse(Error)
ManifestSerialize(Error)
The manifest could not be canonicalised for content-hashing. Serialising our own
derived types is infallible in practice; a typed variant keeps content_hash
panic-free (bp-rust: no expect outside binary entry points).
NoManifestPath
reload_from_disk was called on a Control built from an in-memory manifest (no
backing path). Construct with from_manifest_path / load_at to enable disk reload.
TrustChangeRequiresRestart
A reload’s manifest changed the [trust] section. Trust roots are fixed at
construction (same Host, same epoch ticker — ADR 000006 / 000008); a reload only
swaps the filter set + chain, never the trust policy. Rejecting the change fail-closed
(rather than silently ignoring it) keeps an operator from believing a key rotation took
effect when it did not — rotate trust by restarting with the new manifest.
StateChangeRequiresRestart
A reload’s manifest changed the [state] section. The state backend is fixed at
construction like the trust roots (ADR 000041): the Host holds one KvBackend for
its life, so a backend/path edit cannot take effect on a reload. Rejecting it
fail-closed keeps an operator from believing a durability change took effect when it
did not — change the backend by restarting with the new manifest.
InvalidStateConfig(String)
The [state] section is inconsistent (ADR 000041): redb without a path, or a
path under memory. Rejected fail-closed so a half-edited section never silently
runs on memory while the operator believes state is durable.
StateBackendInit(String)
The configured state backend could not be constructed (ADR 000041): the redb file’s parent directory is missing, or redb failed to open/create the database.
InvalidListenConfig(String)
The [listen] section is inconsistent (ADR 000057): a [listen.proxy_protocol] with an
empty or unparseable trusted CIDR list. Rejected fail-closed — enabling PROXY v2
without declaring who may speak it would mean trusting every peer (deny-by-default, P4).
Io(Error)
IoAt
An I/O failure carrying the file it was for: a bare Io (“No such file or directory
(os error 2)”) gives the operator no hint WHICH referenced file — the manifest, a trust
key, a state dir — was the problem. Preferred over Io wherever the path is known.
TrustKey(String)
HostInit(String)
Artifact
The artifact could not be resolved or was malformed (missing layer, bad layout, …).
DigestMismatch
The resolved artifact’s content digest did not equal the manifest’s pin (ADR 000007 reproducibility / supply-chain integrity). Fail-closed.
Load
The host rejected the filter at the provenance/load gate (ADR 000006 signature/SBOM,
or instantiation). Carries the host’s anyhow error for its message.
InvalidFilterConfig
A filter entry carried an out-of-range metering / rate-limit value (e.g. a zero deadline, zero memory cap, or a rate-limit bucket that can never refill). Rejected fail-closed at build so a config typo cannot reach the host’s metering arithmetic (CWE-20).
UnknownChainFilter(String)
DuplicateFilterId(String)
DuplicateUpstream(String)
EmptyUpstreamAddresses(String)
An upstream declared no addresses (ADR 000017). An upstream must have at least one
instance to forward to; an empty list is fail-closed at build time, not at request time.
UpstreamRegistryPoisoned
The upstream registry’s lock was poisoned (a thread panicked while holding it). Surfaced rather than re-panicked so a reconcile fails closed (the running set stays live).
InvalidUpstreamLb
An upstream’s load-balancing config (ADR 000035) was malformed: a per-instance weight of
zero or over the cap, a maglev upstream without (or a non-maglev upstream with) a
[upstream.hash] block, a header hash key with no header name, a non-prime / out-of-range
table_size, or more instances than the maglev table can index. Rejected fail-closed at
build, before the persistent registry mutates, so a bad LB config never reaches the hot path.
UnknownRouteUpstream
UnknownRouteFilter
InvalidRoute
A route’s forwarding target or weighted traffic split (ADR 000034) was malformed: both or
neither of upstream / backends set, an empty backends, every weight zero, a weight
over the cap, or a reduced split table too large. Rejected fail-closed at build, before the
upstream registry reconciles, so a bad split never mutates persistent state.
InvalidRouteRateLimit
A route’s native rate limit (ADR 000033) had an out-of-range value (rate or burst of
zero — a bucket that can never serve a token). Rejected fail-closed at build, like the
per-filter rate-limit validation, so a config typo cannot reach the limiter arithmetic.
TlsCert
A TLS cert/key file could not be read, parsed, or built into a usable certificate
(ADR 000014). Fail-closed: a bad cert aborts the build, so reload never swaps in a TLS
config that cannot serve. host is the SNI the entry was for (None = default cert).
Stek
The [resumption] shared-STEK config (ADR 000062) is invalid or its key file failed the
fail-closed startup discipline: out-of-range max_age_hours, no [[tls]] cert to bind
tickets to, a key file that is unreadable / not exactly 64 raw bytes / readable by group
or other, or a cert whose SPKI the provider cannot expose (nothing to bind to). All abort
the build like a bad cert — a proxy never comes up sharing ticket keys it cannot protect.
UpstreamTlsCa
An [upstream.tls] CA bundle could not be read or parsed, or yielded no usable root
(ADR 000042). Fail-closed at build, like TlsCert: a bad CA path aborts the build /
reload before the upstream registry mutates, so the forward leg never silently falls
back to unverified (or plaintext) forwarding.
UpstreamTlsSni
An [upstream.tls] sni verification-name override did not parse as a valid DNS name or IP
address (ADR 000050). Fail-closed at build, like UpstreamTlsCa: a bad sni aborts the
build / reload before the upstream registry mutates, rather than letting every handshake
to this upstream fail at request time.
UpstreamClientCert
An [upstream.tls] client identity (upstream mTLS, ADR 000078) could not be built:
client_cert_path / client_key_path set without the other, an unreadable / unparsable
PEM, a key file readable by group or other (the ADR 000062 (d) key-file discipline), or
a chain/key pair rustls rejects. Fail-closed at build, like UpstreamTlsCa: the forward
leg never silently connects WITHOUT the identity the backend requires.
ClientAuthCa
The [listen.client_auth] downstream-mTLS config (ADR 000078) is invalid: no [[tls]]
cert to terminate with, or a ca_path that is unreadable / unparsable / yields no
usable trust anchor. Fail-closed at build: the listener never comes up accepting
clients it was told to authenticate but cannot.
Trait Implementations§
Source§impl Debug for ControlError
impl Debug for ControlError
Source§impl Display for ControlError
impl Display for ControlError
Source§impl Error for ControlError
impl Error for ControlError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<Error> for ControlError
impl From<Error> for ControlError
Source§impl From<Error> for ControlError
impl From<Error> for ControlError
Auto Trait Implementations§
impl !RefUnwindSafe for ControlError
impl !UnwindSafe for ControlError
impl Freeze for ControlError
impl Send for ControlError
impl Sync for ControlError
impl Unpin for ControlError
impl UnsafeUnpin for ControlError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more