This GitLab error occurs when you try to push directly to a protected branch without the required permissions. Protected branches in GitLab require merge requests and appropriate access levels to accept changes.
When GitLab returns this error during a push, it means the branch you're targeting is protected and your account doesn't have permission to push directly to it. GitLab's branch protection is a security feature designed to safeguard critical branches (like `main`, `master`, or `production`) from accidental or unauthorized changes. Protected branches in GitLab enforce one or more of these restrictions: - Only users with specific access levels (Maintainer, Developer, etc.) can push - Only certain users or groups can merge - Force push is disabled - Code owner approval may be required - Merge requests are required for all changes Unlike GitHub's GH006 error which focuses on pull request requirements, GitLab's protected branch model is based on role-based access levels. A Developer might be able to push to some protected branches but not others, depending on configuration. Common scenarios where this error appears: - Developers trying to push to main/master without Maintainer access - CI/CD pipelines using tokens with insufficient permissions - Attempting to push after branch protection rules changed - New team members not yet granted appropriate project access
The intended workflow for protected branches is to use merge requests:
# Create a feature branch from main
git checkout main
git pull origin main
git checkout -b feature/your-changes
# Make your changes and commit
git add .
git commit -m "Add your changes"
# Push the feature branch
git push -u origin feature/your-changesThen create a merge request in GitLab:
1. Go to your project in GitLab
2. Click Code > Merge requests > New merge request
3. Select your feature branch as source and the protected branch as target
4. Fill in the title and description
5. Click Create merge request
This allows code review and CI/CD checks before merging.
Verify your current role and permissions:
1. Go to your project in GitLab
2. Navigate to Settings > Members (or Project information > Members)
3. Find your username and check your role:
- Guest: No push access
- Reporter: No push access
- Developer: Can push to unprotected branches, limited protected branch access
- Maintainer: Can push to most protected branches
- Owner: Full access
If you need elevated access, ask a project Maintainer or Owner to change your role.
If you have Maintainer access, check the branch protection rules:
1. Go to Settings > Repository
2. Expand Protected branches
3. Find the branch (e.g., main) and check:
- Allowed to merge: Who can merge MRs into this branch
- Allowed to push and merge: Who can push directly
- Allowed to force push: Whether force push is permitted
To allow Developers to push directly (if appropriate):
1. Click the branch name or edit icon
2. Under "Allowed to push and merge", select "Developers + Maintainers"
3. Click Protect
Warning: Allowing direct pushes reduces code review protection.
If a CI/CD pipeline needs to push to protected branches:
Option 1: Enable CI_JOB_TOKEN for protected branches
1. Go to Settings > CI/CD
2. Expand Token Access
3. Ensure the job token has appropriate scope
Option 2: Use a Project Access Token
1. Go to Settings > Access Tokens
2. Create a new token with:
- Name: "CI Push Token"
- Role: Maintainer
- Scopes: write_repository
3. Add the token as a CI/CD variable (e.g., PUSH_TOKEN)
4. Update your .gitlab-ci.yml:
push_changes:
script:
- git remote set-url origin "https://oauth2:${PUSH_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git"
- git push origin mainOption 3: Use a Deploy Key with write access
1. Generate an SSH key pair
2. Go to Settings > Repository > Deploy keys
3. Add the public key and check "Grant write permissions"
4. Configure your CI to use the private key
For users who need direct push access (use sparingly):
1. Go to Settings > Repository > Protected branches
2. Find your protected branch
3. Under "Allowed to push and merge", you can:
- Select specific users from the dropdown
- Add specific groups
- Use "Maintainers" or "Developers + Maintainers"
In GitLab Premium/Ultimate, you can also:
- Require code owner approval
- Set up push rules for content validation
- Configure protected branches at the group level
If you need to force push (rebase, amend) to a protected branch:
Option 1: Allow force push (if appropriate)
1. Go to Settings > Repository > Protected branches
2. Edit the branch
3. Toggle "Allowed to force push" if available
4. Note: This is only available for certain roles and may require Premium
Option 2: Use the GitLab UI to rewrite history
For simple cases, use GitLab's UI to squash commits during merge.
Option 3: Create a new branch and replace
# Create a corrected branch
git checkout main
git pull
git checkout -b main-fixed
# Make your corrections
git push origin main-fixedThen have a Maintainer delete and recreate the protected branch (extreme measure).
Best Practice: Avoid force pushing to protected branches. Use merge request squash options instead.
### GitLab Access Levels Explained
GitLab uses a numeric permission model:
- Guest (10): View project, create issues
- Reporter (20): Clone, view CI/CD pipelines
- Developer (30): Push to non-protected branches, create MRs
- Maintainer (40): Push to protected branches, manage project settings
- Owner (50): Full control including deletion
Protected branches can be configured to accept pushes from any of these levels.
### Wildcard Protected Branches
GitLab supports wildcard patterns for protecting multiple branches:
- release-* protects all branches starting with "release-"
- *-stable protects all branches ending with "-stable"
Check if wildcard rules are affecting your branch.
### Group-Level Protected Branches
In GitLab Premium/Ultimate, protected branch settings can be enforced at the group level. If you can't modify settings at the project level, check with your group administrator.
### CI/CD Job Token Limitations
The default CI_JOB_TOKEN has limited permissions and cannot push to protected branches by default. You must either:
1. Use a Project Access Token with Maintainer role
2. Configure job token permissions explicitly
3. Use a personal access token (not recommended for shared runners)
### GitLab vs GitHub Protected Branches
| Feature | GitLab | GitHub |
|---------|--------|--------|
| Access model | Role-based levels | Pull request requirements |
| Error message | "not allowed to push code" | "GH006: Protected branch update failed" |
| Force push control | Per-branch toggle | Per-branch setting |
| Token bypass | Requires Maintainer token | Requires bypass actor list |
### Troubleshooting Push Rules
GitLab also has "Push Rules" separate from protected branches that can reject pushes:
- Go to Settings > Repository > Push rules
- Check for file size limits, secret file detection, or commit message requirements
- These generate different error messages but can be confused with protection errors
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git