opentofu/opentofu · error

json error for azure subscription: %w

Error message

json error for azure subscription: %w

What it means

The Azure client-certificate/CLI auth path runs `az account show -o json` and unmarshals its stdout into a Subscription struct. If the command succeeded but its output is not valid JSON of the expected shape, json.Unmarshal fails and is wrapped as "json error for azure subscription".

Source

Thrown at internal/backend/remote-state/azure/auth/cli_auth.go:98

type Subscription struct {
	Id        string `json:"id"`
	Name      string `json:"name"`
	IsDefault bool   `json:"isDefault"`
}

// getCliAzureSubscriptionID obtains the subscription ID currently active in the
// Azure profile. This assumes the user has the Azure CLI installed on their machine.
func getCliAzureSubscriptionID(ctx context.Context) (string, error) {
	rawSubscription, err := getCurrentSubscriptionInfo(ctx)
	if err != nil {
		return "", err
	}

	var subscription Subscription
	err = json.Unmarshal(rawSubscription, &subscription)
	if err != nil {
		return "", fmt.Errorf("json error for azure subscription: %w", err)
	}

	return subscription.Id, nil
}

// getCurrentSubscriptionInfo is adapted from azure-sdk-for-go's CLI token retrieval
func getCurrentSubscriptionInfo(ctx context.Context) ([]byte, error) {
	cliCmd := exec.CommandContext(ctx, "az", "account", "show", "-o", "json")
	var stderr bytes.Buffer
	cliCmd.Stderr = &stderr

	stdout, err := cliCmd.Output()
	if err != nil {
		msg := stderr.String()
		return nil, fmt.Errorf("error getting subscription info: error: %w\nmore information: %s", err, msg)
	}

	return stdout, nil

View on GitHub (pinned to 3561785c48)

Solutions

  1. Run `az account show -o json` in the same environment and inspect the raw output for non-JSON lines
  2. Upgrade azure-cli to a current stable version (`az upgrade`)
  3. Disable/remove extensions that print banners into stdout
  4. Re-authenticate with `az login` if the profile data is stale or corrupt

Example fix

# before: extensions pollute stdout
az extension add --name connectedk8s  # prints a banner on every command
# after: quiet output, valid JSON only
az extension remove --name connectedk8s
az account show -o json | jq .id
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-flight: output must be valid JSON
az account show -o json | jq -e .id >/dev/null || echo "az output not JSON - fix CLI environment"

Try / catch

if err := json.Unmarshal(raw, &subscription); err != nil {
    // retry once after az upgrade / re-login before giving up
}

Prevention

When it happens

Trigger: az CLI emitting non-JSON noise into stdout (extension banners, warnings, locale-specific text), a very old/new azure-cli printing a different shape, or output polluted by shell profile echo lines.

Common situations: azure-cli extensions or preview versions printing notices; CI images with older az versions; environments where az account show succeeds but streams warnings to stdout instead of stderr.

Related errors


AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15). Data as JSON: /api/errors/a880d1eb38412eea. Report an issue: GitHub.