risingwavelabs/risingwave · error · SecretError
unspecified secret ref type: {0}
Error message
unspecified secret ref type: {0} What it means
SecretError::UnspecifiedRefType is raised when a secret reference carries a SecretId but the reference's type field is not set (unspecified), so the secret resolver cannot tell how to interpret or look up the reference. The SecretId is included in the message for diagnosis.
Source
Thrown at src/common/secret/src/error.rs:34
use thiserror::Error;
use thiserror_ext::Construct;
use super::SecretId;
pub type SecretResult<T> = Result<T, SecretError>;
#[derive(Error, Debug, Construct)]
pub enum SecretError {
#[error("secret not found: {0}")]
ItemNotFound(SecretId),
#[error("decode utf8 error: {0}")]
DecodeUtf8Error(#[from] std::string::FromUtf8Error),
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
#[error("unspecified secret ref type: {0}")]
UnspecifiedRefType(SecretId),
#[error("failed to encrypt or decrypt the secret")]
AesError,
#[error("ser/de proto message error: {0}")]
ProtoError(#[from] bincode::Error),
#[error(transparent)]
Internal(#[from] anyhow::Error),
}
View on GitHub (pinned to 6469eb736d)
Solutions
- Set the reference type explicitly when building the secret ref in the client/SQL layer.
- Upgrade/fix the component that produced the proto so it fills the ref type field.
- Inspect the stored proto message for the given SecretId and re-create it with a valid type.
Example fix
// before
let ref = SecretRef { id: some_id, ..Default::default() }; // type unspecified
resolve(ref)?;
// after
let ref = SecretRef { id: some_id, ref_type: RefType::Compat, ..Default::default() };
resolve(ref)?; Defensive patterns
Strategy: validation
Validate before calling
// Validate a secret ref has a concrete type before resolving:
fn ref_type_is_set(r: &SecretRef) -> bool {
!matches!(r.ref_type, None | Some(RefType::Unspecified))
} Type guard
fn valid_secret_ref(r: &SecretRef) -> Option<&SecretRef> {
match r.ref_type {
Some(RefType::Unspecified) | None => None,
Some(_) => Some(r),
}
} Try / catch
match resolver.resolve(&secret_ref).await {
Ok(secret) => secret,
Err(SecretError::UnspecifiedRefType(id)) => {
// producer bug: ref built without setting its type — reject and re-create
return Err(anyhow!("secret ref {id} has no type; rebuild the reference"));
}
Err(e) => return Err(e.into()),
} Prevention
- Always set the ref type field when constructing secret refs in proto/client code.
- Avoid ..Default::default() on secret ref protos; fill required fields explicitly.
- Keep proto definitions in sync across frontend/meta versions.
- Validate refs at creation time instead of at resolution time.
When it happens
Trigger: Constructing or deserializing a secret ref (e.g. from protobuf) where the type/ref-kind field is left at its default/unspecified value and then attempting to resolve it, producing SecretError::UnspecifiedRefType(id).
Common situations: A protobuf message for a secret reference was built without setting the ref type oneof/enum (default zero value); older clients or proto schema drift omitting a newly required field; hand-written serialization of a secret ref skipping the type.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- ser/de proto message error: {0}
- query_epoch not set in distributed lookup join
- secret not found: {0}
- decode utf8 error: {0}
- I/O error: {0}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/fe95bba0fe3d207f.
Report an issue: GitHub.