dbt-bigquery: 403 Access Denied: User does not have bigquery.jobs.create permission
Fixes dbt-bigquery 403 Access Denied where the identity lacks bigquery.jobs.create. Use when dbt cannot create jobs in the target project. Not for dataset-level table permission errors after jobs start running.
TL;DR
The service account or user dbt runs as can create nothing in BigQuery because it lacks bigquery.jobs.create on the project. Grant roles/bigquery.jobUser (or a custom role containing jobs.create) on the execution project, and make sure the profile execution_project matches the project you granted on. dbt can then submit jobs.
dbt-bigquery: 403 Access Denied: User does not have bigquery.jobs.create permissionUse this when
- dbt run fails immediately with 403 Access Denied User does not have bigquery.jobs.create permission
- the error names the project dbt submits jobs to
- you switched service accounts, projects, or moved from user credentials to a service account
Not for this skill when
- jobs are created but fail reading a source dataset, that needs bigquery.dataViewer on that dataset instead
- the 403 is on a different API such as storage, grant that specific permission
- you use a different warehouse, this IAM model is BigQuery specific
Steps
Read the error fully: note the exact principal and the project named after in project. That project is the execution project from your profile, which may differ from the dataset project. Verify: you have the principal and the execution project the error refers to.
In Google Cloud IAM for that project, check the principal roles. Confirm whether roles/bigquery.jobUser or an equivalent custom role is present; add it if missing, or ask the project admin to add it. Verify: IAM shows the principal with a role containing bigquery.jobs.create on that project.
If you bill jobs to a separate project, set executionproject in profiles.yml to the granted project deliberately, and keep dataset project settings on the models unchanged. Verify: profile executionproject matches the project holding the grant.
Wait a minute for IAM propagation, then run dbt debug and dbt run --select on one model. Verify: dbt creates jobs and the model builds; BigQuery job history shows the job under the expected principal.
Variant phrasings
user credentials work, service account fails
Developers often test with their own account, which has broad roles. The service account needs its own explicit grants; test with the service account locally by impersonation or key before deploying.
403 names a project you do not recognize
A stale GOOGLECLOUDPROJECT environment value or an old profile output can redirect jobs. Print the resolved profile with dbt debug.
Compatibility: dbt-bigquery 1.x with Google Cloud IAM. jobs.create is included in roles/bigquery.jobUser and roles/bigquery.user; grants are per project.
Why it happens
Every dbt operation on BigQuery is a job, so job creation permission is the gate for all work. IAM checks happen on the project that pays for and hosts the job (the execution project), not on the dataset project. A missing jobs.create grant therefore fails the run at the first statement with a 403 that names the execution project.
Edge cases / pitfalls
- IAM changes take up to a few minutes to propagate; an immediate retry can still 403 and mislead you.
- Granting dataViewer on datasets does not include jobs.create; the two most common BigQuery grants solve different errors.
- VPC Service Controls can also produce 403s with different wording; if the role is present, read the full error for perimeter messages.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_Mhz-ZGzjcn2wgXOMoTnDBA