vitessio/vitess · error
a POST request needs a keyspace in the URL
Error message
a POST request needs a keyspace in the URL
What it means
The keyspaces collection handler in the vtctld HTTP API requires the keyspace to be encoded in the URL for POST requests, because a POST represents an action on a specific keyspace. If the POST path has no keyspace segment, this error is returned before form parsing.
Source
Thrown at go/vt/vtctld/api.go:213
handleCollection("keyspaces", func(r *http.Request) (any, error) {
keyspace := getItemPath(r.URL.Path)
switch r.Method {
case "GET":
// List all keyspaces.
if keyspace == "" {
return ts.GetKeyspaces(ctx)
}
// Get the keyspace record.
k, err := ts.GetKeyspace(ctx, keyspace)
if err != nil {
return nil, err
}
// Pass the embedded proto directly or jsonpb will panic.
return k.Keyspace, err
// Perform an action on a keyspace.
case "POST":
if keyspace == "" {
return nil, errors.New("a POST request needs a keyspace in the URL")
}
if err := r.ParseForm(); err != nil {
return nil, err
}
action := r.FormValue("action")
if action == "" {
return nil, errors.New("a POST request must specify action")
}
return actions.ApplyKeyspaceAction(ctx, action, keyspace), nil
default:
return nil, fmt.Errorf("unsupported HTTP method: %v", r.Method)
}
})
handleCollection("keyspace", func(r *http.Request) (any, error) {
// Valid requests: api/keyspace/my_ks/tablets (all shards)
// Valid requests: api/keyspace/my_ks/tablets/-80 (specific shard)View on GitHub (pinned to 01a25a7d17)
Solutions
- Include the keyspace in the URL: POST /api/keyspaces/<keyspace> with action=<action> in the form body.
- If you meant to act on a shard or tablet, use the appropriate endpoint (/api/<keyspace>/shards/... or /api/tablets/...).
- Check the client/script builds the URL from the keyspace variable (it may be empty due to an earlier failed lookup).
Example fix
// before curl -X POST http://localhost:15000/api/keyspaces -d 'action=Refresh' // after curl -X POST http://localhost:15000/api/keyspaces/commerce -d 'action=Refresh'
Defensive patterns
Strategy: validation
Validate before calling
if keyspace == "" {
return fmt.Errorf("cannot POST keyspace action: keyspace is empty")
}
url := fmt.Sprintf("%s/api/keyspaces/%s", base, url.PathEscape(keyspace)) Try / catch
resp, err := http.PostForm(base+"/api/keyspaces/"+keyspace, url.Values{"action": {action}})
if err != nil { /* handler rejected with 'a POST request needs a keyspace in the URL' - fix the URL */ } Prevention
- Interpolate the keyspace into the URL for all keyspace POSTs.
- Fail early in clients when the keyspace variable is empty.
When it happens
Trigger: POSTing to /api/keyspaces (no keyspace in the path), e.g. curl -X POST http://vtctld:15000/api/keyspaces -d 'action=Refresh'.
Common situations: Scripts that POST keyspace actions to the collection root instead of /api/keyspaces/<keyspace>; automation migrating from vtctl commands where the keyspace was a flag; missing URL encoding of the keyspace.
Related errors
- a POST request must specify action
- keyspace is required
- BaseKeyspace is required for SNAPSHOT keyspaces
- SnapshotTime is required for SNAPSHOT keyspaces
- no shards found in keyspace
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/97e11234df589b7f.
Report an issue: GitHub.