CLO-117: reject AWS PrivateLink SERVICE NAME that is not a service name - #38185
Open
jubrad wants to merge 4 commits into
Open
Conversation
CLO-117. A `SERVICE NAME` that is not an AWS VPC endpoint service name, most often the DNS name of the target such as a load balancer hostname, was accepted by `CREATE CONNECTION` and only surfaced later as "The Endpoint cannot be created due to missing availability zones". The environment controller cannot parse such a value as a cross-region service name, so it treats the endpoint as same-region and blames the availability zone list, which points at the wrong option. `AwsPrivatelinkConnection::check_service_name` now rejects values that cannot be endpoint service names, and adds a hint that calls out the DNS name mistake specifically. `VALIDATE CONNECTION` reports it too, so a connection that already stores an offending value gets the true cause instead of the availability zone message. The check runs in the sequencer rather than the planner. The planner also runs against the `create_sql` of items already in the catalog on boot, where a failure panics, so a planner-level rule would turn an environment that already stores an offending value into a crash loop. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`VALIDATE CONNECTION` on an AWS PrivateLink connection whose SERVICE NAME cannot name a VPC endpoint service folded the hint into the error message, because `AwsPrivatelinkConnection::validate` returned an `anyhow::Error` and every such error lands in `ConnectionValidationError::Other`, whose `hint()` is `None`. Give the shape failure its own `ConnectionValidationError` variant, matching how the other connection types carry a typed validation error. The hint now travels in the pgwire HINT field, the same way it already does on the CREATE path via `PlanError::hint`. Part of CLO-117.
Drop the DNS-hostname heuristic. Varying the hint on whether the value parses as a hostname needed a scheme/port/TLD parser and its own tests to change one sentence. The hint now always says a service name is not the DNS name of the target, which covers the mistake without the machinery. Also trim the comments to what the code does not already say.
The hint and the `SERVICE NAME` docs already give the expected shape, which is enough to tell a user their value is wrong.
jubrad
marked this pull request as ready for review
August 13, 2026 14:34
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes CLO-117.
Motivation
A user created an AWS PrivateLink connection with an ELB DNS hostname in
SERVICE NAMEinstead of a VPC endpoint service name:CREATE CONNECTIONaccepted it, and the mistake only surfaced later aswhich points at the wrong option. The environment controller cannot parse that
value as a cross-region service name, so it treats the endpoint as same-region
and reports the empty
AVAILABILITY ZONESlist as the failure.Changes
AwsPrivatelinkConnection::check_service_namerejects values that cannot beAWS VPC endpoint service names. It is deliberately permissive: it requires
only the
com.amazonaws.prefix, so both customer-owned(
com.amazonaws.vpce.<region>.vpce-svc-<id>) and AWS-managed(
com.amazonaws.<region>.<service>) services pass.PlanError::InvalidPrivatelinkServiceNamecarries a hint that gives theexpected shape and says the value is not the DNS name of the target.
CREATE CONNECTIONandALTER CONNECTIONnow fail up front with that error.AwsPrivatelinkConnection::validateperforms the same check before readingendpoint status, so
VALIDATE CONNECTIONon a connection that already storesan offending value reports the true cause instead of the availability zone
message. This is the exact symptom in the report, and it also removes the need
for a new
VpcEndpointStatevariant in the cloud repo.SERVICE NAMEsyntax element now says what the value is and is not.Why the sequencer and not the planner
The obvious home for this is
plan_connection, next to the existingAVAILABILITY ZONESvalidation. That is not safe. Catalog items are re-plannedon boot via
CatalogState::deserialize_item, and a failure there panics(
src/adapter/src/catalog/apply.rs). Any environment that already stores anoffending service name would crash-loop on upgrade, which is precisely the
population this change is about.
with_enable_for_item_parsingdoes not helpeither, since it force-enables flags during item parsing, so a flag-gated
planner rule would still fire on boot.
The sequencer runs only for statements a client issues, so the rule cannot stop
an existing item from loading. For
CREATEthe check precedes id allocation,secret creation, resource-limit validation, and the catalog transaction, so
nothing leaks before the rejection.
Two accepted behavior changes for environments that already store an offending
value:
CREATE CONNECTION IF NOT EXISTSwith the offending name now errors insteadof being a no-op. This matches how existing option validation already behaves
(an invalid
AVAILABILITY ZONESentry errors at plan time regardless ofIF NOT EXISTS).ALTER CONNECTIONre-plans the fullcreate_sql, so it reports the storedoffending name even when the statement does not touch
SERVICE NAME. Settinga valid
SERVICE NAMEin the sameALTERclears it.Tips for reviewer
The permissiveness of the rule is the main thing to sanity check. It is
prefix-only on purpose. Worth confirming with the cloud team that no live
connection uses a service name outside
com.amazonaws.*before this ships,since such a connection would start failing
VALIDATE CONNECTIONandALTER.Checklist
considered. (trigger-ci for additional test/nightly runs)
$T ⇔ Proto$Tmapping (possibly in a backwards-incompatible way), then it is tagged with aT-protolabel.CREATE CONNECTION ... TO AWS PRIVATELINKandALTER CONNECTIONnow rejecta
SERVICE NAMEthat is not an AWS VPC endpoint service name, andVALIDATE CONNECTIONreports that as the cause instead of a missingavailability zone.
🤖 Generated with Claude Code