hasura/graphql-engine · error · errors.Error
citus_run_sql api request failed %d
Error message
citus_run_sql api request failed %d
What it means
CitusRunSQL returns this error when the Hasura server answers the citus_run_sql metadata API call with a non-200 status and an empty response body. Since there is no body text to relay, only the numeric HTTP status is reported. The error carries errors.KindHasuraAPI, indicating the CLI's request was delivered but the server refused to execute the SQL via the Citus source.
Source
Thrown at cli/internal/hasura/sourceops/citus/run_sql.go:35
Type: "citus_run_sql",
Args: input,
}
b := new(bytes.Buffer)
resp, err := d.send(body, b)
if err != nil {
return nil, errors.E(op, err)
}
if resp.StatusCode != http.StatusOK {
if b.Len() > 0 {
return nil, errors.E(op, errors.KindHasuraAPI, b.String())
} else {
return nil, errors.E(
op,
errors.KindHasuraAPI,
fmt.Errorf("citus_run_sql api request failed %d", resp.StatusCode),
)
}
}
o := new(hasura.CitusRunSQLOutput)
if err = json.NewDecoder(b).Decode(o); err != nil {
return nil, errors.E(op, err)
}
return o, nil
}
View on GitHub (pinned to 724551b9ae)
Solutions
- Decode the embedded HTTP status: 401/403 → verify admin secret; 404 → confirm citus source support; 5xx → check Hasura and Citus database logs
- Validate the Citus database connection directly (psql with the same URL) to rule out network/credential issues
- Run the CLI with --debug to see the raw HTTP exchange
- Ensure metadata for the citus source is consistent (POST /v1/metadata with export/inconsistent check)
- Align CLI and server versions
Example fix
// before
out, err := c.CitusRunSQL(args)
if err != nil { return err }
// after
out, err := c.CitusRunSQL(args)
if err != nil {
if strings.Contains(err.Error(), "citus_run_sql api request failed") {
return fmt.Errorf("citus_run_sql rejected; inspect server logs: %w", err)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check source health before running migrations
// POST /v1/metadata {"type":"export_metadata"} → assert a kind:"citus" source with a reachable URL exists Type guard
func isEmptyBodyAPIError(err error) bool {
return err != nil && strings.Contains(err.Error(), "api request failed")
} Try / catch
out, err := c.CitusRunSQL(args)
if err != nil {
if isEmptyBodyAPIError(err) {
return diagnoseFromStatus(err) // 401 vs 404 vs 5xx; then read server logs
}
return err
} Prevention
- Test the Citus connection string with psql before configuring the source
- Automate metadata consistency checks in CI before migrate apply
- Version-pin CLI and server together
When it happens
Trigger: Running 'hasura migrate apply' or another flow that calls citus_run_sql against a server that responds 401/403 (auth), 404 (citus source kind or endpoint missing), or 500 with empty body (target Citus/Postgres database unreachable, bad connection string, or metadata inconsistency).
Common situations: Citius source configured with an unreachable database URL, expired DB credentials, wrong admin secret, Hasura server version lacking the citus plugin, or an infrastructure layer (proxy, service mesh) that discards error bodies.
Related errors
- bigquery_run_sql api request failed %d
- cockroach_run_sql api request failed %d
- run_sql api request failed %d
- run_sql api request failed %d
- pg_dump request: %d %s
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/7c1e0c72c929a163.
Report an issue: GitHub.