neondatabase/neon · critical
pageserver connection information should be provided
Error message
pageserver connection information should be provided
What it means
While turning a ComputeSpec into a ParsedSpec, compute_ctl found no pageserver address: the explicit pageserver_conninfo argument was None and spec.cluster.settings has no 'neon.pageserver_connstring' GUC. Without a pageserver the compute cannot read pages, so parsing aborts. This is a spec-authoring/cplane problem, not a runtime failure.
Source
Thrown at compute_tools/src/compute.rs:336
pageserver_conninfo = Some(PageserverConnectionInfo::from_connstr(
pageserver_connstr_field,
spec.shard_stripe_size,
)?);
}
}
if pageserver_conninfo.is_none() {
if let Some(guc) = spec.cluster.settings.find("neon.pageserver_connstring") {
let stripe_size = if let Some(guc) = spec.cluster.settings.find("neon.stripe_size")
{
Some(ShardStripeSize(u32::from_str(&guc)?))
} else {
None
};
pageserver_conninfo =
Some(PageserverConnectionInfo::from_connstr(&guc, stripe_size)?);
}
}
let pageserver_conninfo = pageserver_conninfo.ok_or(anyhow::anyhow!(
"pageserver connection information should be provided"
))?;
// Similarly for safekeeper connection strings
let safekeeper_connstrings = if spec.safekeeper_connstrings.is_empty() {
if matches!(spec.mode, ComputeMode::Primary) {
spec.cluster
.settings
.find("neon.safekeepers")
.ok_or(anyhow::anyhow!("safekeeper connstrings should be provided"))?
.split(',')
.map(|str| str.to_string())
.collect()
} else {
vec![]
}
} else {
spec.safekeeper_connstrings.clone()View on GitHub (pinned to 8f60b04da4)
Solutions
- Add "neon.pageserver_connstring": "postgresql://..." to spec.cluster.settings (or pass the conninfo through the code path that sets it directly)
- Fix the control-plane spec generation so the pageserver connstring GUC is always included for endpoints that need one
- Pre-validate specs (JSON schema or field check) before handing them to compute_ctl
Example fix
// before: spec.cluster.settings missing the GUC -> error
// after: spec fragment
{
"cluster": {
"settings": [
{ "name": "neon.pageserver_connstring", "value": "postgresql://nouser@pageserver-0:6400" }
]
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate spec before ParsedSpec::try_from / compute start
let has_ps = spec.pageserver_conninfo_arg.is_some()
|| spec.cluster.settings.find("neon.pageserver_connstring").is_some();
if !has_ps {
anyhow::bail!("spec rejected: neon.pageserver_connstring missing");
} Type guard
fn spec_has_pageserver(spec: &ComputeSpec) -> bool {
spec.cluster.settings.find("neon.pageserver_connstring").is_some()
} Try / catch
// Startup-time config error: fail fast with a precise message, do not retry
match ParsedSpec::try_from(spec) {
Ok(p) => p,
Err(e) if e.to_string().contains("pageserver connection") =>
return Err(anyhow!("spec incomplete (pageserver connstring) - fix cplane spec")),
Err(e) => return Err(e),
} Prevention
- Enforce a JSON schema for ComputeSpec at the control plane so the GUC cannot be omitted
- Add contract tests between cplane spec generation and ParsedSpec::try_from
- For local specs, start from a fixture in the repo rather than a blank file
When it happens
Trigger: ParsedSpec::try_from (compute.rs) receives a spec where pageserver_conninfo is None and settings.find("neon.pageserver_connstring") returns None. Typically a hand-written spec.json for testing, or a control plane that omitted the GUC when assembling cluster settings.
Common situations: Local testing with a hand-crafted spec file; version skew where an older/newer cplane stops emitting neon.pageserver_connstring; spec mangled by middleware or manual editing before reaching compute_ctl.
Related errors
- shard {shard_index} missing from pageserver_connection_info
- safekeeper connstrings should be provided
- tenant id should be provided
- timeline id should be provided
- Remote extensions are not configured
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/92f204e85d56035b.
Report an issue: GitHub.