hashicorp/nomad · error

no one-time token returned

Error message

no one-time token returned

What it means

UpsertOneTimeToken() POSTs to /v1/acl/token/onetime to create a short-lived one-time token. If the HTTP call succeeds (no transport or API error) but the decoded response object is nil, the client treats it as an unexpected/empty server response and returns this error. It guards the dereference of resp.OneTimeToken.

Source

Thrown at api/acl.go:220

// Self is used to query our own token
func (a *ACLTokens) Self(q *QueryOptions) (*ACLToken, *QueryMeta, error) {
	var resp ACLToken
	wm, err := a.client.query("/v1/acl/token/self", &resp, q)
	if err != nil {
		return nil, nil, err
	}
	return &resp, wm, nil
}

// UpsertOneTimeToken is used to create a one-time token
func (a *ACLTokens) UpsertOneTimeToken(q *WriteOptions) (*OneTimeToken, *WriteMeta, error) {
	var resp *OneTimeTokenUpsertResponse
	wm, err := a.client.put("/v1/acl/token/onetime", nil, &resp, q)
	if err != nil {
		return nil, nil, err
	}
	if resp == nil {
		return nil, nil, errors.New("no one-time token returned")
	}
	return resp.OneTimeToken, wm, nil
}

// ExchangeOneTimeToken is used to create a one-time token
func (a *ACLTokens) ExchangeOneTimeToken(secret string, q *WriteOptions) (*ACLToken, *WriteMeta, error) {
	if secret == "" {
		return nil, nil, errors.New("missing secret ID")
	}
	req := &OneTimeTokenExchangeRequest{OneTimeSecretID: secret}
	var resp *OneTimeTokenExchangeResponse
	wm, err := a.client.put("/v1/acl/token/onetime/exchange", req, &resp, q)
	if err != nil {
		return nil, nil, err
	}
	if resp == nil {
		return nil, nil, errors.New("no ACL token returned")
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the target is a Consul server version >= 1.6 that supports one-time tokens (acl enabled).
  2. Check any proxies/load balancers between client and server are not returning empty 200 responses.
  3. Retry the operation; if it persists, inspect the server logs for the /v1/acl/token/onetime request.
Defensive patterns

Strategy: try-catch

Type guard

func ottReturned(r *api.OneTimeTokenUpsertResponse) bool { return r != nil && r.OneTimeToken != nil && r.OneTimeToken.SecretID != "" }

Try / catch

ott, _, err := client.ACLTokens().UpsertOneTimeToken(nil)
if err != nil {
    if err.Error() == "no one-time token returned" {
        // verify server version/ACL enabled, then retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling ACLTokens().UppsertOneTimeToken(q) against a server that returns 200 with an empty body, or a proxy/middleware that strips the response body; response payload fails to decode into OneTimeTokenUpsertResponse leaving resp nil.

Common situations: Older Consul servers (pre-1.6) or non-Consul endpoints behind the same address that do not implement the one-time token endpoint; an API gateway returning an empty 200; TLS/proxy interference.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/5e756ee63fd3286e. Report an issue: GitHub.