Skip to content

Troubleshooting

Fixes for common setup and ingestion failures, by cloud and surface. Every table uses the same columns: the symptom you see, its most likely cause, and the fix. If a fix does not resolve the failure, escalate through Support with the failing command’s redacted output and correlation ID. Support is an optional escalation path, never an onboarding gate.

AWS

Symptom Cause Fix
Automated credential validation reports AccessDenied on assume-role The external_id or trusted_principal_arn in terraform.tfvars differs from the generated values. Recopy both values from guided setup, apply, and rerun validation.
verify.sh exits 2 with “could not assume role” when you run it The trust policy accepts only the Venturi principal. Expected. Run the policy listing and the IAM policy simulator spot check in Verify & confirm; automated credential validation runs the live probes.
CUR data is missing The CUR bucket name or prefix does not match terraform.tfvars. Correct cur_bucket_name or cur_report_prefix, apply, and rerun validation.
Bedrock data is missing enable_bedrock_access = false, bedrock_log_group names a different log group, or Bedrock invocation logging is off. Enable access, set the exact log group, and turn on model invocation logging.
terraform apply fails on iam:CreateRole The setup principal cannot create IAM roles. Apply as a principal that can create the role and its inline policies, such as one with IAMFullAccess.

Google Cloud

Symptom Cause Fix
“unauthorized_client” or “subject not allowed” wif_allowed_subjects is missing the exact subject Venturi presents. Copy the exact generated subject, with no wildcards, and apply.
BigQuery query returns empty billing_dataset_id names a dataset that does not exist or is not the billing export. Check the dataset with bq ls, correct the ID, and apply.
Vertex AI logs missing Cloud Logging exclusion filters drop Vertex AI entries before they are stored. Remove or narrow the exclusion for the metadata logs Venturi reads.
terraform apply fails creating the Workload Identity Pool The caller lacks roles/iam.workloadIdentityPoolAdmin. Grant the role to the setup principal, or apply from a CI runner that holds it.
terraform apply fails setting an IAM binding on the project, the service account, or the billing dataset The setup principal lacks roles/resourcemanager.projectIamAdmin, roles/iam.serviceAccountAdmin, or IAM authority on the dataset, such as roles/bigquery.dataOwner. Grant the missing role to the setup principal and apply again.
verify.sh prints role: roles/bigquery.dataViewer billing_dataset_only is false or billing_dataset_id is empty, so the module granted BigQuery reads on the whole project. The script’s allowlist accepts that role, so it reports no SEC line. Set billing_dataset_id and billing_dataset_only = true, apply, and rerun verify.sh.
verify.sh exits 2 or reports permission errors although you ran gcloud auth application-default login verify.sh uses the gcloud CLI account, not Application Default Credentials. Run gcloud auth login as the principal that runs the check, then rerun.
verify.sh reports the write probe as SKIP The caller lacks roles/iam.serviceAccountTokenCreator on the service account. Not a failure on its own, provided the project-scope role lines are exactly roles/monitoring.viewer, roles/logging.viewer, and roles/serviceusage.serviceUsageConsumer; automated credential validation runs the denied-write probes as Venturi’s identity. To exercise the write probe as well, grant the role for the check, rerun, then remove it.
verify.sh prints a role: line other than roles/monitoring.viewer, roles/logging.viewer, and roles/serviceusage.serviceUsageConsumer, such as roles/iam.serviceAccountTokenCreator or roles/iam.workloadIdentityUser A project-scope binding outside the module. The script’s allowlist accepts several such roles and prints them as OK, and a project-scope token-creator or workload-identity-user binding lets its holder obtain tokens for every service account in the project. Security finding. Disable the connector, remove the binding, apply, and rerun verify.sh.
verify.sh prints MISS WIF pool although the pool exists The identity running the script cannot list Workload Identity pools. Grant it roles/iam.workloadIdentityPoolViewer on the project, or run the check as the setup principal, then rerun.
terraform apply or validation fails with SERVICE_DISABLED or “API has not been used in project” The project does not have an API that Workload Identity Federation or impersonation needs: IAM, Resource Manager, Service Account Credentials, or Security Token Service. Enable the named API with gcloud services enable as a principal with roles/serviceusage.serviceUsageAdmin, wait a few minutes, then apply or validate again (see Connect Google Cloud).
terraform apply fails with Not found: Dataset for the billing dataset billing_dataset_id names a dataset that is not in project_id, or that does not exist. Set it to the billing-export dataset in project_id. The module connects 1 project and cannot grant access to a dataset in another project.

Azure

Symptom Cause Fix
“AADSTS70021” or “no matching federated identity record” The issuer, subject, or audience does not match the federated credential. Compare the generated issuer and subject, and the api://AzureADTokenExchange audience, with the credential; correct terraform.tfvars and apply.
Cost Management returns empty Subscription-scope roles see costs only when the billing agreement exposes them there. For an Enterprise Agreement, an Enterprise admin enables AO view charges on the billing account (enrollment). Otherwise, confirm the billing scope that holds the charges: an EA billing account, department, or enrollment account; a Microsoft Customer Agreement billing account, billing profile, or invoice section; or a CSP billing account, billing profile, or customer.
Azure OpenAI usage missing Inference flows through API Management or Event Hubs, and the matching grant is off. Enable the matching grant with its workspace or namespace resource ID, then apply.
terraform apply fails on azuread_application or azuread_service_principal The setup identity cannot register applications, or a CI principal with Application.ReadWrite.OwnedBy is not an owner of the objects it manages. Use a human operator who can register applications, such as the Application Developer role, or a CI principal with Microsoft Graph Application.ReadWrite.OwnedBy, admin consent, and ownership of both the app registration and the service principal.
terraform apply fails on a role assignment The setup identity lacks Owner, User Access Administrator, or Role Based Access Control Administrator on the subscription. Use an identity with 1 of those roles. Global Administrator alone does not grant Azure RBAC; a Global Administrator can elevate access to User Access Administrator at root scope, assign the role, and then remove the elevation.
terraform plan or apply fails while registering Azure resource providers The module pins azurerm ~> 3.80, which tries to register every resource provider it supports that is not yet registered, and the setup identity cannot register providers. User Access Administrator and Role Based Access Control Administrator cannot; Owner can. Run export ARM_SKIP_PROVIDER_REGISTRATION=true, then terraform init and terraform plan again.
The --all role assignment listing shows a role outside the access boundary, such as Reader and Data Access or Billing Reader An assignment the module never makes. The script’s allowlist accepts those roles, so it reports no SEC line; Reader and Data Access can read and write all data in a storage account through its account keys. Security finding. Disable the connector, remove the assignment, and rerun the checks.
verify.sh reports write probes SUCCEEDED The script ran under a privileged az session; its write probes use the signed-in identity. Under Owner, the role-assignment and resource-group probes succeed; under User Access Administrator or Role Based Access Control Administrator, only the role-assignment probe succeeds. The script removes the Contributor assignment it created; confirm with az role assignment list --assignee "$OBJECT_ID" --all. Under Owner, also delete the venturi-verify-must-fail-<timestamp> resource group. Sign in as a Reader-only identity and rerun.
verify.sh reports Azure Event Hubs Data Receiver outside its allowlist Event Hubs access is enabled with an empty event_hub_namespace_id, so the role landed at subscription scope. Set the namespace resource ID and apply.
verify.sh prints role: Log Analytics Reader APIM access is enabled with an empty apim_log_analytics_workspace_id, so the role landed at subscription scope and reaches every workspace. The script’s allowlist accepts it, so it reports no SEC line. Set the workspace resource ID and apply.
terraform output fails after you sign in as the Reader-only identity A Reader-only identity cannot read Terraform state kept in the azurerm backend. Capture client_id and object_id as the setup operator before you switch identity, as shown in Verify & confirm.

verify.sh and policy checks

Each row maps a verify.sh exit code or an AWS policy-check result to its fix.

Symptom Cause Fix
Exit 1 with a SEC line, an AWS simulator row shows allowed, the AWS policy listing shows an attached policy or an action outside the access boundary, a Google Cloud role: line falls outside the exact 3-role list, or the Azure --all listing shows a role outside the access boundary Security finding: a write succeeded or is allowed, a role or action is outside the module’s grants, or a user-managed key exists. The Google Cloud and Azure scripts print some extra roles as OK and still exit 0, so read the role lines and the listing. Stop. Disable the connector, remove the grant or key, apply, and rerun the complete check. On Azure, confirm the script ran as a Reader-only identity.
Exit 2 The script could not find or read the identity it checks: the AWS role assumption, the Google Cloud service account or IAM policy, or the Azure service principal or role assignments. Confirm the environment variables and the signed-in identity, then rerun.
Exit 0 with MISS lines A read probe or a required object check did not complete, so the boundary is only partly proven. Fix the named item and rerun; do not treat the run as a pass. The only expected MISS is the absent federated credential in the Azure client-secret fallback.
Exit 0 with a Google Cloud write-probe SKIP line The caller cannot impersonate the service account, so the write probe did not run. Not a failure on its own; see the Google Cloud row above.
An error such as SERVICE_ACCOUNT_EMAIL env var is required (Google Cloud) or CLIENT_ID env var is required (Azure) A required environment variable is not set. Set the variables shown in Verify & confirm.

Ingestion API

Symptom Cause Fix
401 Unauthorized The Authorization: Bearer or X-API-Key header is missing or invalid. Send a valid credential in one of those headers.
400 Bad Request The Idempotency-Key header is missing. Send a client-generated UUID or ULID in Idempotency-Key, and keep it stable when you retry the same event (see Idempotency).
403 Forbidden The credential is not authorized for the ingestion routes, or the request names a tenant other than the credential’s. Use a credential that meets the ingestion authentication requirements, and do not send a tenant identifier that differs from the credential’s tenant.
422 Unprocessable Entity The payload failed schema validation, or an Idempotency-Key was reused with a different body. Send the required fields (event_id, ingestion_layer, ingestion_timestamp, provider, requested_model), use a schema value such as OTEL for ingestion_layer, and send estimated_cost_usd as a JSON number, not a quoted string. Reuse an Idempotency-Key only with the identical body.
Event accepted (202) but not in the dashboard The event is still processing, or you are viewing a different tenant or instance. Allow approximately 30 seconds, then check the Invocation feed; confirm you are querying the same tenant and instance.

Proxy

Symptom Cause Fix
Calls work but are not attributed The proxy records the call but has no identity hint. Add the identity header your platform team configured.
Latency concern The decision-time interceptor has a 50 ms P99 end-to-end budget, with a cooperative timeout against a cumulative deadline. None needed for safety: on a timeout or failure of a Venturi dependency behind the proxy, the proxy forwards the request unmodified. Report sustained latency above that budget through Support.
Calls fail because the proxy endpoint cannot be reached The proxy endpoint is on your request path; fail-open covers the Venturi dependencies behind it, not the endpoint itself. Configure client-side failover to the provider’s direct base URL (see Proxy endpoint reachability), then check the status surface.

Contact support

Give feedback on this page

Sign in to send feedback. Opens in a new tab.

Copy page details
Docs feedback: Troubleshooting
Page: https://docs.venturi.systems/reference/troubleshooting/