Skip to content

token create: persistent upstream 500 on POST /v2/storage/tokens surfaces as a blind retry + generic error, no actionable guidance #599

Description

@vojtechnovotny-heu

Summary

kbagent token create against a project on the europe-west3.gcp (EU GCP) stack fails every time with a raw 500 from the Keboola Storage API. Investigation shows kbagent itself is behaving correctly (correct request, retries per its documented policy, faithfully surfaces the upstream error) — this looks like an upstream Storage API defect, not a kbagent bug. Filing here anyway because (a) kbagent is the only way I have to observe/reproduce it, and (b) there's a concrete CLI-side hardening gap exposed by it (see "Proposal").

Environment

  • kbagent v0.84.2 (keboola-cli PyPI package)
  • Stack: connection.europe-west3.gcp.keboola.com

Repro

kbagent -v token create -p <project> -d "<description>" --expires-in 60

Response: 500 {"error": "Application error."} from POST /v2/storage/tokens, retried 3x by kbagent's existing backoff policy (500 is in RETRYABLE_STATUS_CODES), all 3 attempts fail identically.

Ruled out as the cause, so this doesn't look like a request-shape bug on the client side:

  • Reproduces on 2 different projects on the same stack, with 2 different acting tokens.
  • Reproduces with no scope, and with --bucket-read on a real bucket.
  • Reproduces with --expires-in 60, --expires-in 3600, and omitted entirely (never expires).
  • Acting token confirmed to have canManageTokens — rules out the missing-permission theory (which per http_base.py's own _raise_api_error should surface as a clean 403ErrorCode.ACCESS_DENIED, not a 500).
  • No incident reported for the europe-west3 stack on status.keboola.com / keboolastatus.com at the time of testing.

Proposal

Not asking for a fix to the upstream API from this repo — that's a Keboola Connection backend issue I'll raise with Keboola support separately. But two things are actionable in kbagent itself:

  1. Non-idempotent retry risk: POST /v2/storage/tokens is a create/mint call, not idempotent, yet it's retried on 500/502/503/504 like any other request. If the API ever creates the token server-side and then fails to respond cleanly (unlike this case, where all 3 attempts failed identically with no sign of partial success), a blind retry could silently mint a duplicate live credential the caller never sees. Worth excluding mutating/non-idempotent endpoints from the generic retry policy, or gating the retry on an idempotency key.
  2. Generic 500 message gives no next step: today this surfaces as API error 500 ... Application error. with no hint that a persistent 500 (survives all retries, stable across projects/tokens/payloads) is very likely an upstream incident rather than something the caller can fix. A short, specific hint in the ErrorCode.API_ERROR 500 path (e.g. "if this persists across retries/projects, it's likely an upstream Keboola incident — contact Keboola support") would save the next person the same investigation.

Open questions

  • Is there a better internal channel (Keboola support / a status page not covered by status.keboola.com or keboolastatus.com) that kbagent maintainers already use to escalate confirmed upstream 500s like this one? If so, pointing to it from the error message would be more useful than a generic hint.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions