Category Archives: glm

How to Fix Git Push Rejected Error: A Complete Troubleshooting Guide

How to Fix Git Push Rejected Error: A Complete Troubleshooting Guide

Picture this: It is Friday afternoon. You have been grinding on a complex feature all week. The code is clean, the tests pass, and you are ready to push your branch to the remote repository and wrap up the week. You type git push origin main, hit Enter, and instead of the satisfying flow of objects being compressed and uploaded, you are met with a wall of red text.

The dreaded [rejected] error.

If you are searching for exactly how to fix git push rejected error scenarios, take a deep breath. You are in the right place. As a senior developer, I have seen this error haunt everyone from junior devs on their first day to seasoned architects. A rejected push is not a failure; it is Git’s way of telling you that the remote repository has evolved since you last synced, or that a specific rule is being enforced.

In this comprehensive troubleshooting guide, we are going to dissect the root causes of this error, walk through step-by-step solutions (from the most common scenarios to rare edge cases), and arm you with the preventative habits needed to avoid it in the future.


Understanding the Root Cause of a Rejected Push

Before we start fixing things, it helps to understand why Git rejects a push. Git is designed to never intentionally lose data. When you try to push your local commits to a remote branch (like main or develop), Git checks to ensure your local history is a direct, linear descendant of the remote history.

If the remote branch has commits that your local branch does not have, Git rejects your push. It does this to prevent you from accidentally overwriting someone else’s work.

When you run into this, Git will usually output something that looks like this:

! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'git@github.com:username/repository.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.

Essentially, your local timeline and the remote timeline have diverged. To fix this, we need to reconcile those timelines.


Scenario 1: Non-Fast-Forward Updates (The Most Common Culprit)

The vast majority of the time, this error happens because someone else on your team pushed code to the same branch while you were working locally. Your local main branch is now “behind” the remote main branch.

Solution A: Git Pull with Rebase (The Cleanest History)

When looking at how to fix git push rejected error messages, the cleanest approach is usually a rebase. Standard git pull creates a merge commit, which can clutter your project’s history. Pulling with --rebase takes your local commits, temporarily removes them, updates your branch with the remote commits, and then replays your local commits on top.

Step 1: Fetch and Rebase
Run the following command in your terminal:

git pull --rebase origin main

Step 2: Resolve Conflicts (If Any)
If your changes overlap with the changes your teammates pushed, Git will pause the rebase and ask you to resolve merge conflicts.

Open your code editor, find the files with conflicts (usually marked with <<<<<<< HEAD and >>>>>>>), and fix them.

Once resolved, stage the files and continue the rebase:

git add .
git rebase --continue

Note: Do not run git commit during a rebase unless specifically instructed. Just add the files and continue.

Step 3: Push Your Changes
Now that your local branch is perfectly synced with the remote, push your code:

git push origin main

Solution B: Git Pull with Merge (The Default Approach)

If your team prefers a explicit record of when branches were synced (a merge commit), you can use the default pull behavior.

git pull origin main

This will fetch the remote changes and create a new “merge commit” tying your local history and remote history together. If there are conflicts, resolve them in your editor, save the file, stage it, commit it, and finally run git push origin main.

Solution C: Force Pushing (Proceed with Extreme Caution)

Sometimes, you know you want to overwrite the remote history. This is common when you are working alone on a feature branch, or when you are updating an open-source fork and want to completely sync it with the upstream repository.

If you are wondering how to fix git push rejected error logs on a branch you alone control, you can force push:

git push -f origin my-feature-branch

Warning: Never force push to shared branches like main, master, or develop. Overwriting shared history will cause massive headaches for your teammates and can permanently delete commits.

If you want to be slightly safer, use the --force-with-lease flag. This will only force push if no one else has added new commits to the remote branch since your last fetch:

git push --force-with-lease origin my-feature-branch

Scenario 2: Remote Rejected (Branch Protection Rules)

In modern development workflows, pushing directly to main is often disabled. Platforms like GitHub, GitLab, and Bitbucket allow repository administrators to set up “Branch Protection Rules.”

If you try to push to a protected branch, your push will be rejected with a specific message, often mentioning GH006 or similar server-side error codes.

Example error:

remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Changes must be made through a pull request.
 ! [remote rejected] main -> main (protected branch hook declined)

The Fix: Create a Feature Branch and a Pull Request

You cannot force your way past branch protection rules (unless you are an admin with bypass permissions). The proper solution is to use the Git branching workflow.

Step 1: Create a new branch
Ensure you are on the updated main branch, then create a new feature branch:

git checkout main
git pull origin main
git checkout -b feature/new-login-system

Step 2: Commit and Push the Branch
Make your changes, stage them, commit them, and push the new branch to the remote:

git add .
git commit -m "feat: implement new login system"
git push -u origin feature/new-login-system

(Note: The -u flag sets the upstream tracking reference. The next time you are on this branch, you can just type git push and Git will know where to send it).

Step 3: Open a Pull Request
Navigate to your GitHub/GitLab repository in your browser. You will see a prompt to “Compare & pull request.” Click it, fill out the PR template, and let your team review the code before merging it into main.


Scenario 3: Pre-Receive Hook Declined (Server-Side Policies)

Sometimes, your code is rejected not because of branch protection, but because of server-side hooks. Companies often set up automated checks that run the moment you push. If your code fails these checks, the push is rejected.

Common reasons include:
* Commit messages failing a regex pattern (e.g., not conforming to Conventional Commits).
* Commit author email not matching your company email domain.
* Pushing secrets (like AWS keys) detected by scanning tools.

Example error:

remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
remote: ERROR: commit abc1234: email address j.doe@gmail.com is not allowed.
remote: Committer must use a corporate email address.
To github.com:company/project.git
 ! [remote rejected] main -> main (pre-receive hook declined)

The Fix: Rewriting Commit Metadata or Correcting Errors

If the hook rejected your push because of an invalid email address or a poorly formatted commit message, you need to rewrite your local commits before pushing again.

To fix the last commit’s author details:

git commit --amend --author="John Doe <john.doe@company.com>"

To fix a bad commit message:

git commit --amend -m "fix: correct typo in user authentication"

If you have multiple commits with the wrong email, you will need to use an interactive rebase to change them all:

git rebase -r HEAD~3 --exec 'git commit --amend --reset-author --no-edit'

This command takes the last 3 commits and resets the author to your current global Git configuration without changing the commit message. Once the metadata is clean, you can push successfully.


Scenario 4: Large Files Exceeding Limits

Git is designed to track text-based source code. It struggles with massive binary files (like database dumps, uncompressed videos, or large zip archives). If you attempt to push a file exceeding your Git hosting provider’s limit (GitHub has a strict 100MB limit, for instance), the push will fail.

Example error:

remote: error: File sql/dataset.sql is 152.67 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: GH001: Large files detected.
 ! [remote rejected] main -> main (pre-receive hook declined)

The Fix: Remove the File from History and Use Git LFS

Simply deleting the file and committing the deletion will not work. The large file still exists in your Git history. Git remembers everything.

How to Fix Terraform Apply Errors: The Definitive Troubleshooting Guide

It’s 2 AM. The pipeline is broken. You run terraform apply, cross your fingers, and instead of the satisfying green glow of provisioned infrastructure, your terminal vomits a red, terrifying block of text.

We have all been there. Nothing spikes a DevOps engineer’s heart rate quite like a failed production deployment. Infrastructure as Code (IaC) is supposed to make our lives easier, but when things go wrong, Terraform’s state management and declarative model can turn a minor typo into a four-hour debugging nightmare.

If you are currently staring at a broken terminal, take a deep breath. Welcome to the definitive guide on the terraform apply error how to fix phenomenon. As a senior developer who has spent more hours staring at .tfstate files than I care to admit, I am going to walk you through the root cause analysis, step-by-step solutions for the most common (and infuriating) errors, and the preventative measures you need to implement to ensure you never end up here again.

Grab a coffee. Let’s fix your infrastructure.

Understanding the Beast: Root Cause Analysis of Terraform Failures

Before we start slinging code and running commands, we need to understand why terraform apply fails.

A terraform plan might look perfect, but apply is where the rubber actually meets the road. It transitions from local computation to making real-time API calls to your cloud provider (AWS, GCP, Azure).

When you ask yourself, “what is the terraform apply error how to fix strategy for this specific traceback?”, you need to categorize the error into one of four root causes:

  1. State Drift: The real-world infrastructure no longer matches your .tfstate file because someone made manual changes in the AWS Console.
  2. Authentication & Authorization: Your CI/CD runner’s OIDC token expired, or your local IAM credentials lack specific permissions.
  3. Dependency Graph Issues: Terraform is trying to destroy or create resources in the wrong order, resulting in API violations (e.g., trying to delete a VPC before deleting its subnets).
  4. API Rate Limiting and Timeouts: You tried to spin up 1,000 EC2 instances simultaneously, and the AWS API told you to slow down.

Whenever an apply fails, ask yourself which of these four buckets the error falls into. Once you know that, the fix becomes trivial.

The Step-by-Step Troubleshooting Playbook

We are going to walk through the most common errors from easiest to hardest. I’ll give you the exact terminal commands you need to copy and paste.

Scenario 1: The Dreaded State Lock Error

The Error:

Error: Error acquiring the state lock
Lock Info:
  ID:        12345-abcde-67890-fghij
  Path:      terraform.tfstate
  Operation: OperationTypeApply
  Who:       developer@sexydeveloper.net
  Version:   1.9.0
  Created:   2026-10-27 10:00:00.000000 +0000 UTC

The Root Cause:
Terraform uses a locking mechanism (usually DynamoDB if you are using S3 as a backend) to prevent concurrent runs. If your CI/CD pipeline crashes mid-apply, or you accidentally hit Ctrl+C on your local machine, the lock is never released. Terraform thinks someone is still applying changes.

The Fix:
First, verify that no one else is actually running a terraform apply right now. Check your CI/CD dashboard. If the coast is clear, you need to forcefully unlock the state using the ID provided in the error message.

# Copy the ID from the error output
terraform force-unlock 12345-abcde-67890-fghij

Type yes when prompted. Run your terraform apply again. Crisis averted.

Scenario 2: State Drift (The “Already Exists” or “Not Found” Error)

The Error:

Error: creating EC2 Instance: InvalidKeyPair.NotFound: The key pair 'my-ssh-key' does not exist

OR

Error: ResourceAlreadyExistsException: The resource you are trying to create already exists.

The Root Cause:
This is state drift. A colleague (or maybe you, at 5 PM on a Friday) manually deleted that SSH key in the AWS Console, or manually created an S3 bucket via the CLI. Terraform’s state file doesn’t know about this discrepancy until it tries to apply.

The Fix:
You need to realign Terraform’s state with the real world.

First, figure out exactly what has drifted. Run a refresh-only plan to see the delta without applying any changes:

terraform plan -refresh-only

If a resource was manually deleted, you can tell Terraform to recreate it by simply running terraform apply.

However, if a resource was manually created outside of Terraform and is now clashing, you have two choices:
1. Delete the manually created resource via the Cloud Console.
2. Import the real-world resource into your Terraform state.

To import it, grab the real-world ID (e.g., an S3 bucket name or EC2 instance ID) and use the import block or CLI command:

# Using the CLI approach
terraform import aws_instance.my_web_server i-0abcd123456789ef0

Note: In modern Terraform (1.5+), you can also use an import block directly in your code, which is much cleaner for version control:

import {
  to = aws_instance.my_web_server
  id = "i-0abcd123456789ef0"
}

Run terraform plan to see how Terraform will reconcile the imported state with your configuration, and then run terraform apply.

Scenario 3: Provider Authentication and Credential Failures

The Error:

Error: error configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found.

OR

Error: ExpiredToken: The security token included in the request is expired

The Root Cause:
Terraform acts as an API wrapper. If the API rejects your identity, Terraform fails. Locally, your AWS SSO or aws iam credentials might have expired. In a CI/CD environment (like GitHub Actions or GitLab CI), your OIDC tokens or static secrets might be misconfigured or revoked.

The Fix:

If you are working locally:
Simply refresh your cloud credentials. If you use AWS CLI profiles:

# Log in via SSO again
aws sso login --profile my-dev-profile

# Verify your identity
aws sts get-caller-identity --profile my-dev-profile

Once authenticated, run terraform apply again.

If you are in a CI/CD Pipeline:
Ensure your pipeline is assuming the correct IAM role via OIDC. This is a common pain point. Check your pipeline’s OIDC configuration. Here is a standard GitHub Actions snippet for dynamic AWS credentials (hardening best practice for 2026):

# .github/workflows/terraform.yml
jobs:
  terraform:
    runs-on: ubuntu-latest
    permissions:
      id-token: write # Required for OIDC
      contents: read
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsTerraform
          aws-region: us-east-1

Scenario 4: Provider Upgrade and Schema Incompatibilities

The Error:

Error: Required plugin version mismatch

OR

Error: Unsupported block type: This object does not have an attribute named "example_attribute"

The Root Cause:
Cloud providers constantly update their APIs, and the Terraform providers (like hashicorp/aws) update alongside them. If your state was created with Provider v4.x, but your team recently bumped the provider to v5.x in the terraform block, the state schema might be incompatible. Attributes get renamed or removed.

The Fix:
Look at your terraform.lock.hcl file and your version constraints.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0" # Was previously 4.x
    }
  }
}

If a recent upgrade caused the apply error, do not panic. State migrations are usually handled automatically by the provider during terraform init.

Run an initialization to upgrade the providers and migrate the state:

terraform init -upgrade

Then, run a terraform plan. If the plan succeeds without errors, you are safe to apply. If the provider upgrade changed attribute names (e.g., AWS S3 bucket ACL changes), you will need to manually update your .tf files to match the new provider schema before applying.

Scenario 5: Dependency Graphs and Order of Operations (Edge Case)

The Error:

Error: deleting EC2 Subnet: DependencyViolation: The subnet 'subnet-abcd' has dependencies and cannot be deleted.

The Root Cause:
Terraform builds a Directed Acyclic Graph (DAG) to understand the order in which resources depend on each other. Sometimes, implicit dependencies aren’t caught by the graph. Terraform tries to delete a VPC before it deletes the EC2 instances and Network Interfaces inside it. The Cloud Provider’s API rejects the deletion.

The Fix:
You need to explicitly tell Terraform about the dependency using the depends_on meta-argument.

Find the resource that is failing to delete (or create) and link it to the resource it is secretly relying on:

resource "aws_subnet" "main" {
  vpc_id = aws_vpc.main.id

  # Explicitly tell Terraform this subnet depends on the instance
  # being destroyed first.
  depends_on = [ 
    aws_instance.my_app_server 
  ]
}

Alternatively, if you are dealing with a massive state file and just need to unblock production right now, you can use targeted applies to force the order manually:

# Destroy the instance first
terraform destroy -target aws_instance.my_app_server

# Now apply the rest of the infrastructure changes
terraform apply

Scenario 6: API Rate Limiting and Timeouts (Edge Case)

The Error:

Error: waiting for EC2 Instance creation: timeout while waiting for state to become 'success'

OR

Error: RequestLimitExceeded: Request limit exceeded.

The Root Cause:
Cloud providers limit the number of API requests you can make per second. If you are deploying a massive Kubernetes cluster or hundreds of microservices simultaneously, Terraform will hit the API rate limit. Alternatively, the underlying cloud provider is just having a bad day and is slow, causing Terraform’s default timeout (usually 10-20 minutes) to expire.

The Fix:
First, tweak your provider configuration to handle retries automatically. Modern provider configurations allow you to set retry logic.

“`hcl
provider “aws” {
region = “us