AWS ECR Image Push Access Denied — Every Fix (2026)
docker push to ECR fails with 'Access Denied' or 'no basic auth credentials'. Here's every cause — expired token, wrong region, missing IAM permissions, ECR URI mismatch — and the exact fix for each.
You run docker push to your AWS ECR repository and get:
denied: User: arn:aws:iam::123456789:user/deploy is not authorized to perform: ecr:InitiateLayerUpload
or
no basic auth credentials
or
Error response from daemon: Get "https://123456789.dkr.ecr.us-east-1.amazonaws.com/v2/": unauthorized
Here's every cause and the exact fix.
How ECR Authentication Works
ECR uses temporary Docker credentials that expire after 12 hours. The flow:
- You call
aws ecr get-login-password→ AWS returns a temporary password - You run
docker loginwith that password → Docker stores it locally - Now you can push/pull for up to 12 hours
If anything breaks in this chain, you get access denied.
Fix 1: Re-authenticate (Most Common Cause)
Your ECR token expired. This is the most common cause, especially in CI/CD pipelines.
# Authenticate Docker to ECR — run this FIRST every time
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789012.dkr.ecr.us-east-1.amazonaws.comReplace:
us-east-1with your actual ECR region123456789012with your actual AWS account ID
After this succeeds, retry your push.
In CI/CD pipelines: Run this command at the start of every job that pushes to ECR. Don't cache ECR credentials between pipeline runs.
Fix 2: Wrong Region in the ECR URI
Symptom: Auth succeeds but push fails with no basic auth credentials for a different registry.
# Check your ECR URI carefully
# WRONG — region mismatch
aws ecr get-login-password --region us-east-1 | docker login ... us-west-2.amazonaws.com
# The auth was for us-east-1 but you're pushing to us-west-2
docker push 123456789.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
# FAILS — different registry, not authenticatedFix: Make sure the region in your get-login-password matches the region in your ECR repository URI. If your repo is in ap-south-1, authenticate against ap-south-1.
REGION="ap-south-1"
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
ECR_REGISTRY="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com"
aws ecr get-login-password --region $REGION | \
docker login --username AWS --password-stdin $ECR_REGISTRY
docker push $ECR_REGISTRY/myapp:latestFix 3: Missing IAM Permissions
Symptom: Authentication works but push fails with explicit deny:
denied: User: arn:aws:iam::123456789:user/ci-user is not authorized to perform: ecr:InitiateLayerUpload
Check the user's permissions:
aws iam get-user --user-name ci-user
aws iam list-attached-user-policies --user-name ci-user
aws iam list-user-policies --user-name ci-userRequired IAM permissions for ECR push:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": "arn:aws:ecr:us-east-1:123456789012:repository/myapp"
}
]
}Attach this policy to your IAM user or role. Note: ecr:GetAuthorizationToken must apply to * (it's account-level, not repository-level).
Fix 4: ECR Repository Doesn't Exist Yet
Symptom:
name unknown: The repository with name 'myapp' does not exist in the registry with id '123456789012'
You need to create the repository first:
aws ecr create-repository \
--repository-name myapp \
--region us-east-1 \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256Then push.
Fix 5: ECR Repository Policy Denying Access
ECR has resource-based policies separate from IAM policies. A restrictive repository policy can deny access even to admins.
Check the repository policy:
aws ecr get-repository-policy \
--repository-name myapp \
--region us-east-1If there's an explicit Deny, fix or remove it:
# Remove the repository policy entirely (revert to IAM-only control)
aws ecr delete-repository-policy \
--repository-name myapp \
--region us-east-1Or update the policy to allow your user/role:
aws ecr set-repository-policy \
--repository-name myapp \
--region us-east-1 \
--policy-text '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPush",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/ci-role"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
]
}
]
}'Fix 6: Cross-Account ECR Access
Symptom: You're pushing from Account A to a repository in Account B.
Fix: The ECR repository in Account B needs a resource-based policy allowing Account A:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CrossAccountPush",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_A_ID:root"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
]
}And the entity in Account A still needs ecr:GetAuthorizationToken permission.
Fix 7: GitHub Actions / CI-specific Issues
Problem: ECR auth works locally but fails in CI.
# GitHub Actions — correct ECR auth pattern
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $REGISTRY/myapp:$IMAGE_TAG .
docker push $REGISTRY/myapp:$IMAGE_TAGUse the official amazon-ecr-login action — it handles authentication automatically including the region detection.
Debugging Checklist
Run through this when ECR push fails:
# 1. Check your AWS identity
aws sts get-caller-identity
# 2. Re-authenticate to ECR
aws ecr get-login-password --region YOUR_REGION | \
docker login --username AWS --password-stdin YOUR_ACCOUNT.dkr.ecr.YOUR_REGION.amazonaws.com
# 3. Check repository exists
aws ecr describe-repositories --repository-names YOUR_REPO --region YOUR_REGION
# 4. Verify IAM permissions (simulate the API call)
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789:user/ci-user \
--action-names ecr:InitiateLayerUpload \
--resource-arns arn:aws:ecr:us-east-1:123456789:repository/myapp
# 5. Check repository policy
aws ecr get-repository-policy --repository-name YOUR_REPO --region YOUR_REGIONThe simulate-principal-policy command is invaluable — it tells you exactly whether a specific action is allowed or denied and why.
ECR access issues almost always come down to expired tokens, wrong region, or missing IAM permissions. The debugging checklist above catches 95% of cases in under 5 minutes.
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
AWS ECS Task Keeps Stopping — How to Fix It (2026)
Your ECS task starts and then immediately stops or keeps restarting. Here's every reason this happens and how to debug and fix it.
AWS ALB 504 Gateway Timeout — Every Cause and Fix (2026)
Your ALB returns 504 Gateway Timeout but the app seems fine. Here's every reason this happens — backend timeouts, keepalive mismatches, health check failures — and exactly how to fix each one.
AWS ALB Showing Unhealthy Targets — How to Fix It
Fix AWS Application Load Balancer unhealthy targets. Covers health check misconfigurations, security group issues, target group problems, and EKS-specific ALB controller debugging.