neondatabase/neon · error · DownloadError::BadInput
Remote extensions storage is not configured
Error message
Remote extensions storage is not configured
What it means
ComputeNode::download_extension needs a base URL for the remote extension archive storage, taken from compute_ctl's -r/--remote-ext-base-url startup parameter (params.remote_ext_base_url). It was None, so the request fails immediately with DownloadError::BadInput before any network I/O. The process was started without extension storage configured, yet something asked to download an extension.
Source
Thrown at compute_tools/src/compute.rs:2419
}
format!("{{\"pg_stat_statements\": [{}]}}", result_rows.join(","))
} else {
"{{\"pg_stat_statements\": []}}".to_string()
}
}
// download an archive, unzip and place files in correct locations
pub async fn download_extension(
&self,
real_ext_name: String,
ext_path: RemotePath,
) -> Result<u64, DownloadError> {
let remote_ext_base_url =
self.params
.remote_ext_base_url
.as_ref()
.ok_or(DownloadError::BadInput(anyhow::anyhow!(
"Remote extensions storage is not configured",
)))?;
let ext_archive_name = ext_path.object_name().expect("bad path");
let mut first_try = false;
if !self
.ext_download_progress
.read()
.expect("lock err")
.contains_key(ext_archive_name)
{
self.ext_download_progress
.write()
.expect("lock err")
.insert(ext_archive_name.to_string(), (Utc::now(), false));
first_try = true;
}View on GitHub (pinned to 8f60b04da4)
Solutions
- Start compute_ctl with --remote-ext-base-url pointing at the extension storage (e.g. the public S3 web bucket) and restart the endpoint
- If extensions are not needed, stop requesting/downloading remote extensions for this compute (and remove them from shared_preload_libraries) so the code path is never hit
- For air-gapped installs, host a mirror of the extension archives and pass its URL
Example fix
# before compute_ctl run --spec spec.json # after compute_ctl run --spec spec.json --remote-ext-base-url https://extensions.neon.tech/v0.2
Defensive patterns
Strategy: validation
Validate before calling
// Before requesting extensions, confirm the compute was started with storage
if compute.params.remote_ext_base_url.is_none() {
anyhow::bail!("this compute has no --remote-ext-base-url; remote extensions unavailable");
} Type guard
fn extensions_available(params: &ComputeParams) -> bool {
params.remote_ext_base_url.is_some()
} Try / catch
// The HTTP extension route already models this: return 503-style early instead of attempting the download
match compute.download_extension(name, path).await {
Err(DownloadError::BadInput(e)) if e.to_string().contains("Remote extensions storage") => {
(StatusCode::SERVICE_UNAVAILABLE, "remote extension storage not configured")
}
other => other,
} Prevention
- Bake --remote-ext-base-url into every compute_ctl launch template (prod, staging, dev)
- Fail the deployment at boot if extension storage is unset but specs reference extensions
- Document the flag next to any docs about enabling remote extensions
When it happens
Trigger: compute_ctl launched without the --remote-ext-base-url flag (or env equivalent feeding it), then the extension server / remote-extensions path calls download_extension() for a requested extension archive.
Common situations: Self-hosted or dev deployments that omit the public extension bucket URL; a docker/VM image whose startup script lost the flag; proxy/air-gapped installs pointing at a nonexistent mirror; spec asks for extensions on a build that intentionally disabled remote extensions.
Related errors
- Remote extensions are not configured
- error downloading extension {:?}: {:?}
- pageserver connection information should be provided
- safekeeper connstrings should be provided
- tenant id should be provided
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/8ba073bb21ce66bf.
Report an issue: GitHub.