GitLab: "insufficient_scope" — "The request requires higher privileges than provided by the access token."
The access token is valid, but it was created without a scope this API call needs. GitLab refuses the call with HTTP 403 and names, in the answer, the scopes that would be accepted. Create a new token that has one of them, and replace the old one wherever it was entered. Rotating the old token does not help: the new one keeps the same scopes.
The whole answer
As GitLab builds it (lib/api/api_guard.rb), for a call that a token with api or read_api could make:
HTTP 403
WWW-Authenticate: Bearer realm="Protected by OAuth 2.0", error="insufficient_scope",
error_description="The request requires higher privileges than provided by the access token.", scope="api read_api"
{"error": "insufficient_scope",
"error_description": "The request requires higher privileges than provided by the access token.",
"scope": "api read_api"}
scope lists the scopes that can authorize this call, separated by spaces; any one of them is enough. Some GitLab versions also list read_api when the call changes something (a 2023 report shows {scope: api read_api} for creating a merge request), but read_api only reads: for a change, the scope to add is api.
Many tools show only the first line, or only "403 Forbidden". To see the whole answer, call the address that failed with curl:
curl -i --header "PRIVATE-TOKEN: your-token" "https://gitlab.com/api/v4/the/address/that/failed"
The token's own scopes are listed next to it on the Personal access tokens page in GitLab.
If GitLab answers 401 "invalid_token" instead, the token itself has expired or been revoked: see what happened to the token.
Which scope does what
From GitLab's access token scopes:
- api: complete read and write access to the API. Anything that changes something needs it: approving, commenting and merging a merge request, retrying, cancelling or running a pipeline.
- read_api: read access to the API. Enough to read merge requests, pipelines and their jobs, never to change them.
- read_user: only your own profile through
/user, and read-only/users. It does not read projects, merge requests or pipelines. - read_repository: pulling over Git (HTTPS) and the repository files API. write_repository: pulling and pushing over Git; GitLab says it does not support API authentication.
A token made for Git alone (read_repository or write_repository) therefore gets insufficient_scope on almost every API call, and one with read_api gets it on the first change. Project and group access tokens have the same scopes, except read_user, which is for personal access tokens only.
For the GitLab integration built into JetBrains IDEs, JetBrains' help asks for a token with the api and read_user scopes (GitLab account).
Create a token with the scope
- In GitLab: your avatar in the upper-right corner, Edit profile, then Access > Personal access tokens in the left sidebar (the names in GitLab's docs on October 24, 2026; older versions differ). From Generate token, choose Legacy token.
- A name, an expiry date, and the scopes: the ones you had plus one from scope (api for a change). GitLab can also open the form with them filled in, for example
https://gitlab.com/-/user_settings/personal_access_tokens?name=IDE&scopes=api(prefilling a token; on a Self-Managed server, use its address). - Copy the token. GitLab shows it only until you leave or refresh the page.
- Put the new token where the old one was, and revoke the old one on the same page. Rotate is not the fix here: it creates a token with the same permissions and scope as the original.
GitLab merge requests and pipelines in IntelliJ IDEA
Lesstep makes two plugins for JetBrains IDEs 2024.1 or later that read GitLab with read_api and change things with api: Merge Request Inbox for GitLab and Pipeline Inbox for GitLab CI. When GitLab answers insufficient_scope, they say which scope the token needs (read_api or api to read, api for a change) and offer to open their settings, which have a link to GitLab's form with the name and scope filled in (GitLab 16.7 or later). Reading is free; approving, commenting and merging, or retrying, cancelling and running pipelines, are Pro (US$1.50 a month, with a 30-day trial).
GITLAB is a trademark of GitLab Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by GitLab Inc. or JetBrains.
More: GitLab merge refused (405, 409, 422) · GitLab approval refused (401, 409) · GitLab comment or thread refused (400, 403) · GitLab merge request not created (409, 422, 400) · GitLab rebase refused or failed (403, 409) · GitLab merge request list refused (400, 404) · GitLab merge request changes cut short ("1000+", too_large) · GitLab 429 "Retry later" (rate limits) · GitLab "compare_timeout": true (diff limits) · GitLab merge request plugins for IntelliJ IDEA, compared · GitLab pipelines in JetBrains IDEs, compared · 日本語