databendlabs/databend · error
Iceberg load_table response did not contain vended…
Error message
Iceberg load_table response did not contain vended credentials
What it means
The Iceberg catalog's `load_table` succeeded, but the response did not carry vended storage credentials where `VendedCredential::from_table` expects them (config/properties on the table metadata). The provider returns this error because without vended credentials it cannot hand temporary storage credentials to the I/O layer.
Solutions
- Enable credential vending / remote signing on the Iceberg catalog and table (e.g. S3 Signer / vended-credentials support in the REST catalog).
- Verify `VendedCredential::from_table`'s expected config keys match what your catalog version actually returns; upgrade the catalog if it predates support.
- As a workaround, configure static storage credentials on the Databend connection/catalog config instead of relying on vending.
- Check the catalog's load_table response (config section) with curl to see which properties are actually present.
Defensive patterns
Strategy: fallback
Validate before calling
// before relying on vending, check the catalog advertises it:
// GET {catalog}/v1/config -> look for "s3.signer" / vended-credentials capability
fn catalog_supports_vending(cfg: &serde_json::Value) -> bool {
cfg.get("signer").is_some() || cfg.get("capabilities").and_then(|c| c.get("vended-credentials")).is_some()
} Try / catch
match provider.load().await {
Err(e) if e.to_string().contains("did not contain vended credentials") =>
fallback_to_static_credentials(),
other => other,
} Prevention
- Enable credential vending / remote signing on the Iceberg catalog
- Pin a catalog version that supports vended credentials
- Configure static storage credentials as a documented fallback
When it happens
Trigger: Catalog/server is not configured for credential vending (no `s3.signer` / remote-signing or vended-credential config on the table or catalog), so the load_table response lacks the expected config entries.
Common situations: Iceberg REST catalog without vended-credentials/signing enabled, table created by another engine that never stored storage credentials, catalog version too old to support credential vending, mismatch between expected property key and what the catalog returns.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- failed to refresh Iceberg table credentials
- not implemented
- not implemented
- s3.access-key-id and s3.secret-access-key must be…
- s3.session-token requires s3.access-key-id and…
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/fe81183175eb7f03.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/storages/iceberg/src/credential.rs:110
trait VendedCredentialProvider: Send + Sync {
async fn load(&self) -> anyhow::Result<VendedCredential>;
}
struct CatalogCredentialProvider {
catalog: Arc<dyn iceberg::Catalog>,
table_ident: TableIdent,
}
#[async_trait]
impl VendedCredentialProvider for CatalogCredentialProvider {
async fn load(&self) -> anyhow::Result<VendedCredential> {
let table = self
.catalog
.load_table(&self.table_ident)
.await
.map_err(|error| anyhow!("failed to refresh Iceberg table credentials: {error:?}"))?;
VendedCredential::from_table(&table).ok_or_else(|| {
anyhow!("Iceberg load_table response did not contain vended credentials")
})
}
}
struct RefreshingAwsCredentialLoader {
provider: Arc<dyn VendedCredentialProvider>,
current: Mutex<VendedCredential>,
}
impl RefreshingAwsCredentialLoader {
fn new(provider: Arc<dyn VendedCredentialProvider>, current: VendedCredential) -> Self {
Self {
provider,
current: Mutex::new(current),
}
}
}
View on GitHub (pinned to 288d84d76e)