diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index 6a10d4fb1c3e..ba38120bf1e6 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -589,6 +589,10 @@ async fn timeline_create_handler( StatusCode::SERVICE_UNAVAILABLE, HttpErrorBody::from_msg(e.to_string()), ), + Err(e @ tenant::CreateTimelineError::AncestorArchived) => json_response( + StatusCode::NOT_ACCEPTABLE, + HttpErrorBody::from_msg(e.to_string()), + ), Err(tenant::CreateTimelineError::ShuttingDown) => json_response( StatusCode::SERVICE_UNAVAILABLE, HttpErrorBody::from_msg("tenant shutting down".to_string()), diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 53cbaea621eb..2aebf4f99932 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -563,6 +563,8 @@ pub enum CreateTimelineError { AncestorLsn(anyhow::Error), #[error("ancestor timeline is not active")] AncestorNotActive, + #[error("ancestor timeline is archived")] + AncestorArchived, #[error("tenant shutting down")] ShuttingDown, #[error(transparent)] @@ -1698,6 +1700,11 @@ impl Tenant { return Err(CreateTimelineError::AncestorNotActive); } + if ancestor_timeline.is_archived() == Some(true) { + info!("tried to branch archived timeline"); + return Err(CreateTimelineError::AncestorArchived); + } + if let Some(lsn) = ancestor_start_lsn.as_mut() { *lsn = lsn.align();