ECR "Authorization Token Has Expired": Login Fixes
If Amazon ECR tells you Your authorization token has expired. Reauthenticate and try again., get a fresh password with aws ecr get-login-password and pipe it to docker login --username AWS --password-stdin for the exact registry and Region. ECR authorization tokens last 12 hours. The unexpected trap: no basic auth credentials during docker push can be the same stale-login problem, even though the message says nothing about token expiration. For recurring work, configure the ECR Docker credential helper or log in at the start of every CI job.
Jake runs a phone-repair shop with a small booking application. His shop has a scheduled release after closing, but the build runner cannot push a new image to Amazon ECR. His fictional $60 weekend campaign depends on that release, and rerunning the same failing Docker command is not helping. The real issue is not whether the image exists locally; it is whether the Docker client has valid registry credentials when the push begins.
Ethan spots a helpful clue: the same pipeline pushed successfully yesterday, and today Docker reports an authentication failure before finishing the upload. That makes credential lifetime and runner setup sensible first checks. It still leaves room for a wrong Region, incorrect repository permissions, or a different Docker configuration directory, so the article follows a decision path rather than prescribing blind relogins.
Read the ECR expired-token error without guessing
You may see denied: Your authorization token has expired. Reauthenticate and try again. on a Docker pull, push, or image deployment. It means the authorization credential being presented to the registry is no longer valid. Docker does not automatically turn an old static password into a fresh ECR authorization token. Request a new password through AWS credentials that still have permission to call the registry.
Amazon Elastic Container Registry, or ECR, stores container images. Docker knows registry usernames and passwords, whereas AWS normally authorizes API calls with IAM credentials. The ECR token bridges those two systems: the AWS CLI gets a short-lived registry password on behalf of the current IAM principal. The username you provide to Docker is literally AWS, not your IAM username.
The token is valid for 12 hours and has an authorization scope corresponding to the IAM principal that retrieved it. A token is not a permission upgrade. A principal unable to push to a repository will still be unable to push after a successful registry login. That separation explains why some Docker errors survive a fresh authentication command.
Start by copying the full Docker error and image tag. The hostname in an image such as 123456789012.dkr.ecr.us-east-1.amazonaws.com/booking-api:release identifies the registry account and Region. Compare it with the hostname you used for login before touching IAM permissions. Most useful fixes begin with matching these strings exactly.
Jake: "The image is built already, so why does the registry care about yesterday’s login?"
Ethan: "The image is ready to deliver, but your delivery badge expired. The registry checks the badge when you push or pull, not when Docker builds the image."
Why the ECR authorization token expires after 12 hours
A token obtained through GetAuthorizationToken has a 12-hour validity period. That duration applies to the authorization token itself, not necessarily to the underlying AWS identity session. For example, an AWS role session might expire before the token’s advertised lifetime, preventing you from obtaining a replacement until the source credentials are refreshed. Keep the two clocks separate in your troubleshooting.
A developer may log in before lunch, suspend a laptop, and attempt a late-night push with the same stored Docker credential. A long-running self-hosted runner might reuse a home directory for days and accidentally reuse an expired entry. Kubernetes can also retain a Docker registry secret containing an old ECR token, even while the pod specification still points at a valid image. All three scenarios need fresh credentials at the point of use.
Docker authentication success is not proof that a particular image push is authorized. Login verifies that Docker can obtain or store a credential for the registry. Repository operations also depend on AWS authorization, repository existence, and the network path. A 403 after a successful login should prompt a permission and hostname review, not only repeated token refreshes.
The 12-hour period does not imply you should schedule logins once every twelve hours on every machine. A short CI job can log in at its start. An interactive workstation can use a credential helper. A container platform should use a runtime mechanism that refreshes image-pull authorization or rotates any manually created secret before it expires.
Use the first five checks to separate token, account, and permission problems
Before changing policies, inspect the exact Docker registry address and current AWS identity. Running aws sts get-caller-identity reveals the account and assumed identity that AWS CLI is actually using. Then compare it with the account embedded in the Docker tag. Cross-account push or pull can work with correct policies, but it should be intentional rather than an unnoticed mismatch.
Next confirm the AWS Region. Private ECR registry login uses a password retrieved for the Region hosting the repository. A token fetched from one Region cannot be used as a general substitute for another. Be explicit with --region in both local commands and CI rather than relying on a forgotten default profile.
Check that Docker and the AWS CLI run as the same operating-system user you expect. A login executed under one home directory may not be visible to a later command using sudo or a different service account. Docker selects configuration from its effective user environment, and DOCKER_CONFIG can override the default location. An apparently successful login can therefore land in a configuration file the next command will not read.
Finally confirm what failed first. If aws ecr get-login-password itself returns an AWS credential or AccessDenied error, Docker cannot repair it. If login succeeds but push reports 403, review the target repository permissions. If the push reports no basic auth credentials, check stale or missing Docker credential storage, the exact registry hostname, and the helper configuration.
| What you see | Likely branch | First check |
|---|---|---|
| Token expired after earlier success | Stored ECR password outlived 12 hours | Refresh via get-login-password |
| no basic auth credentials during push | Missing, stale, or wrong-host credential | Registry hostname and Docker config |
| AWS CLI says ExpiredToken | Source AWS session invalid | Refresh SSO, role, or runner credentials |
| Login succeeds, push returns 403 | Repository authorization or Region mismatch | IAM, repository policy, and tag |
| Only sudo docker push fails | Different Docker config user | User home and DOCKER_CONFIG |
| Kubernetes ImagePullBackOff | Pull-secret age or node identity | Events, secret, node role |
- Identify the exact ECR registry hostname in the image tag and the AWS Region that hosts the repository.
- Run
aws sts get-caller-identityin the same execution environment as the failing build. - Retrieve an ECR password for that Region and pipe it to Docker login using the bare hostname.
- Retry the push or pull, then investigate repository authorization if the fresh login alone is insufficient.
Docker login to ECR on Linux
On Linux, log in with the AWS CLI and Docker installed. Confirm that Docker is running and your AWS identity can request an ECR token. For private ECR in the ordinary AWS partition, replace the example account and Region with the values in your repository URI. Use the registry host without the image path.
aws sts get-caller-identity
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789012.dkr.ecr.us-east-1.amazonaws.com
The pipeline sends the password to Docker through standard input instead of embedding it in a command-line argument. It avoids exposing the password in shell history as a literal value. For robust shell automation, run with set -o pipefail where supported so an AWS CLI failure is not masked by the pipeline’s final command. Handle any failed command before attempting push.
After login, tag the image with the complete ECR repository address and push the same address. The login hostname and the image hostname must match. A repository must already exist or be created through an applicable ECR repository creation mechanism; Docker push does not universally create arbitrary ECR repositories. Check the repository name before changing authentication again.
docker tag booking-api:latest \
123456789012.dkr.ecr.us-east-1.amazonaws.com/booking-api:latest
docker push \
123456789012.dkr.ecr.us-east-1.amazonaws.com/booking-api:latest
If you routinely use sudo docker, remember that root may have a different Docker config file than your normal login account. Prefer a controlled daemon-access setup rather than scattering credentials across user profiles. If you deliberately use root, manage the root credential helper and permissions separately. The key test is whether the process invoking Docker is using the credential you just supplied.
Docker login to ECR on macOS
On macOS, the private ECR login command is the same as on Linux. Open Terminal, confirm that the AWS CLI and Docker client are accessible, and ensure Docker Desktop is running. A successful docker --version check confirms that the client is installed, but a push also requires a working Docker daemon. If Docker reports a daemon connection problem, resolve it before revisiting credentials.
aws sts get-caller-identity
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789012.dkr.ecr.us-east-1.amazonaws.com
macOS Docker setups often use a native credential store for ordinary registry logins. The presence of that store does not make an ECR authorization token permanent. If you used manual login, the stored token still expires after twelve hours. A dedicated ECR credential helper provides a better routine for a machine that frequently pushes images.
You can install the ECR credential helper through the package method appropriate to your environment; its project lists a Homebrew formula named docker-credential-helper-ecr. Once installed, configure Docker to call ecr-login for the ECR registry. This is a different arrangement from merely having Docker Desktop or the macOS keychain installed. Verify the helper executable is on the PATH visible to Docker.
For a one-off release, fresh manual login is perfectly reasonable. For multiple repositories and intermittent work throughout the week, the helper removes the need to remember token renewal. In either case, make sure the AWS profile active at push time belongs to the intended account. A correct credential helper using the wrong profile can still access the wrong set of registries.
Docker login to ECR on Windows PowerShell
Windows users can run the same basic pipeline from PowerShell with AWS CLI v2 and Docker Desktop. Use the PowerShell terminal rather than pasting a Unix-specific multiline backslash command. The following sample is one line so it is easy to paste into Windows Terminal or a normal PowerShell session. Replace the example registry hostname with the target account and Region.
aws sts get-caller-identity
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
If AWS CLI cannot locate credentials, examine your configured profile or SSO session first. If Docker reports that it cannot connect to the engine, start Docker Desktop and check the selected Docker context. Those failures occur before ECR can authenticate anything. Keep authentication, Docker daemon availability, and push permissions as separate steps.
Some older Windows Docker credential-manager configurations had trouble with registry hostnames containing a URL scheme. Pass the bare registry hostname, such as 123456789012.dkr.ecr.us-east-1.amazonaws.com, rather than an https:// URL when calling docker login. This also makes the login host match the host in the image tag. Skip the old docker login -p pattern that places the ECR password directly on the command line.
PowerShell users should also identify the Windows account executing the later push. A scheduled task, Windows service, or build agent can run with a different config.json and AWS profile from your interactive terminal. If an interactive login succeeds but automation fails, inspect the automation identity. A credentials fix performed only in your own profile will not necessarily affect that runner.
Jake: "I logged in on the Windows desktop, but my build task still says no credentials."
Ethan: "Your desktop user and the build service can have separate credential drawers. Put authentication in the job or configure the helper for the actual runner account."
Fix docker push: no basic auth credentials
The exact message no basic auth credentials often appears during docker push or docker pull when Docker cannot supply usable registry authentication. It may be caused by an expired ECR token, but it does not prove expiration by itself. Wrong registry addresses, a missing Docker configuration, a failed helper, and insufficient permission can produce similar symptoms. Follow the shorter proof path before changing your repository policy.
First, run the AWS identity command and perform a fresh ECR login for the hostname shown in your image tag. Then retry the Docker operation immediately. If it now succeeds, the issue was tied to credential state or a stale login. If it fails, inspect the full error, the registry account, and your permission boundary instead of automatically repeating the same login command.
aws sts get-caller-identity
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/booking-api:latest
On systems with an ECR credential helper, an old manually stored Docker token can take precedence and interfere with the helper. Remove the old registry credential using docker logout for the bare registry host, then try a pull or push while the helper is configured. Docker should ask the helper to obtain usable authorization. Only use this procedure if the helper is correctly installed and the current AWS identity can access the repository.
docker logout 123456789012.dkr.ecr.us-east-1.amazonaws.com
docker pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/booking-api:latest
Also check the image tag itself. Running docker login against account A and pushing an image tagged for account B does not establish authentication to B. Likewise, a password from us-west-2 is not the correct answer for a private registry in us-east-1. When two failures look identical, compare the literal hostnames before investigating more complex networking or policy settings.
If you are tired of typing the login line every morning, this section is for you. You install one small helper, you add one line to your Docker config, and you stop thinking about the 12-hour token entirely. Your AWS credentials still have to be valid, but you will not be logging in by hand again.
Use amazon-ecr-credential-helper so you stop manually logging in
The Amazon ECR Docker credential helper obtains registry credentials when Docker needs them. It uses AWS credentials available to its process and caches ECR authorization information rather than requiring a person to call docker login repeatedly. This does not make the 12-hour token permanent. It moves refresh handling into the supported helper workflow, provided the underlying AWS credentials remain valid.
Install the docker-credential-ecr-login executable through the supported package for your platform. On Amazon Linux 2023, the package is amazon-ecr-credential-helper; Ubuntu and Debian also provide packages under that name. On macOS, a Homebrew package is available. Windows binaries are distributed through the project releases. Confirm the executable is discoverable in the effective Docker client environment.
sudo dnf install -y amazon-ecr-credential-helper # Amazon Linux 2023
# Ubuntu or Debian:
sudo apt update
sudo apt install amazon-ecr-credential-helper
# macOS with Homebrew:
brew install docker-credential-helper-ecr
Configure a per-registry helper in ~/.docker/config.json on Linux or macOS, or %USERPROFILE%\.docker\config.json on Windows. The following JSON ensures that Docker uses ECR-specific credentials for this example host without altering other registries. Preserve existing keys such as auths, credsStore, or additional credHelpers as appropriate. The hostname key is the registry host, not a full image URL.
{
"credHelpers": {
"123456789012.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"
}
}
Once the helper is selected, you generally run docker push and docker pull directly without manual login. The helper obtains a token using configured AWS credentials, including supported profiles and role-based sources. It takes its AWS credentials from the usual chain, so for teams using SSO the fix is to refresh the underlying AWS session when it expires.
If the helper was configured after manual Docker login, clear the old saved ECR entry with docker logout so Docker does not reuse a stale token. Check for an inadvertent DOCKER_CONFIG override or a helper missing from PATH. In a shared server environment, keep a single user’s Docker and AWS credential files locked down rather than broadly readable. Set up the helper for the actual service account or use a role-based runtime integration instead.
Troubleshoot a credential helper that still fails
A helper is not a substitute for AWS authorization. If its source IAM role cannot call ecr:GetAuthorizationToken, it cannot obtain a registry token. If the identity has no push permission on a repository, the helper can return a usable login credential while Docker still gets denied. Separate credential acquisition from authorization to repository operations.
Inspect the effective Docker configuration and locate the ECR hostname under credHelpers. The helper name must be ecr-login, which maps to the executable docker-credential-ecr-login. If Docker claims the credential helper executable is missing, the problem is installation or PATH, not token lifetime. Check whether the process is running as root, a Windows service, or a CI runner user.
The helper caches authorization data locally by default. In special environments where you cannot persist a token cache, the project supports disabling it through AWS_ECR_DISABLE_CACHE. That can increase authentication API calls, so use it for a clear operational reason rather than as the default response to every failure. The cache directory can also be controlled through AWS_ECR_CACHE_DIR.
When investigating, keep passwords out of logs and ticket descriptions. The get-login-password output is a password, not harmless diagnostic data. You can collect the AWS identity, registry host, IAM policy names, and sanitized error message without printing that secret. If a pipeline has already logged a real password, treat it as exposed and follow the team’s credential incident procedure.
Distinguish authentication from ECR repository permissions
Successful login establishes Docker authentication, but ECR still authorizes each push or pull. A developer who can pull might not be able to push. A CI role might have ECR token permission but lack permission to initiate an image upload or put an image manifest. The error can be reported as a 403 instead of a neat IAM AccessDenied message.
For private ECR push, the principal generally needs ecr:GetAuthorizationToken and repository actions including ecr:BatchCheckLayerAvailability, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, and ecr:PutImage. Pull workflows use actions such as ecr:BatchGetImage and ecr:GetDownloadUrlForLayer. The exact policy should be limited to the repositories and operations the workload needs.
Account-level authorization-token retrieval is a separate IAM permission and is commonly granted using a resource value of *. Repository-scoped actions can be limited to specific repository ARNs. Cross-account users may additionally need repository policies in the destination account. Use the actual principal from aws sts get-caller-identity when reviewing these permissions.
A repository policy cannot correct a local Docker password that has already expired. Conversely, refreshing a token cannot bypass an explicit deny in a permission boundary, organization policy, or destination repository policy. This is why the order matters: obtain a valid token, establish the intended registry, and then inspect repository authorization if the push or pull remains denied.
| Operation | Representative IAM requirements | Common mistake |
|---|---|---|
| Fetch Docker password | ecr:GetAuthorizationToken | CLI identity lacks authorization-token action |
| Push image | InitiateLayerUpload, UploadLayerPart, CompleteLayerUpload, PutImage, BatchCheckLayerAvailability | Role only has pull permission |
| Pull image | BatchGetImage, GetDownloadUrlForLayer | Node or job role does not have pull access |
| Cross-account operation | IAM plus destination repository authorization | Login account and target repository account differ |
Everything above assumed a laptop. If your failure is in CI, you have the same problem in a less forgiving place: nobody is there to re-run the login. You fix it by making the login part of the job itself, and the next three sections show you exactly where that line goes.
Fix ECR login in GitHub Actions
GitHub-hosted runners are normally temporary, so treat every job as a fresh environment. Authenticate to AWS inside the job, then authenticate Docker before building and pushing. The AWS-supported login action makes this straightforward. Use GitHub OIDC and an IAM role with appropriate permissions instead of saving long-lived AWS access keys when your repository and organization permit it.
The following workflow logs in to a private registry and pushes a sample image. The referenced IAM role and ECR repository must already exist, and the role trust policy must allow the GitHub workflow identity to assume it. Adjust the branch, role ARN, and Region to match your deployment. The sample uses the login action’s returned registry hostname rather than manually constructing a second one.
name: Push to ECR
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-ecr-push
aws-region: us-east-1
- id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: booking-api
TAG: ${{ github.sha }}
run: |
docker build -t "$REGISTRY/$REPOSITORY:$TAG" .
docker push "$REGISTRY/$REPOSITORY:$TAG"
If your workflow has separate build and publish jobs, each job has its own runner environment unless you deliberately reuse one. A Docker login performed in one job does not automatically authenticate a different job. Prefer having the job that performs the push obtain its own fresh credentials. Passing registry passwords between jobs increases complexity and can expose secrets if masking is configured incorrectly.
The ECR login action v2 masks password outputs by default. Leave masking enabled unless your workflow explicitly needs cross-job password outputs and you understand the security consequences. Long builds can also cross the 12-hour token limit if login happens far before push. In that case authenticate as close to the push as possible or refresh the credential before deployment.
Jake: "GitHub gave my job a fresh server. Why did my push still fail?"
Ethan: "A fresh runner still needs AWS identity and a Docker registry login in the job that pushes. Clean machines remove stale state, but they cannot supply credentials on their own."
Fix expired ECR credentials in GitLab CI
GitLab CI jobs also need an authentication plan for their actual execution environment. A job that invokes Docker commands can retrieve an ECR password shortly before push. Make sure AWS CLI is installed in the job image or available on the runner, and configure appropriate AWS credentials. Use short-lived credentials through a suitable runner identity or OIDC federation when available.
This example assumes a GitLab runner with a shell executor where AWS CLI and Docker are already installed. It avoids assuming that a generic docker image contains the AWS CLI. The AWS account and Region values are project CI/CD variables, and the job fails before pushing if the credential retrieval or Docker login fails. Keep sensitive configuration in your normal GitLab protected or masked secret setup.
stages:
- publish
push_ecr:
stage: publish
script:
- set -e
- export REGISTRY="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
- aws sts get-caller-identity
- aws ecr get-login-password --region "$AWS_DEFAULT_REGION" | docker login --username AWS --password-stdin "$REGISTRY"
- docker build -t "$REGISTRY/booking-api:$CI_COMMIT_SHORT_SHA" .
- docker push "$REGISTRY/booking-api:$CI_COMMIT_SHORT_SHA"
A Docker-in-Docker executor requires its own Docker daemon and compatible job image; adapt the setup before copying the commands. A private ECR image used as the GitLab job’s image: must be pulled before the job script starts. In that special case, authentication inside script: is too late. Configure the GitLab Runner or Docker credential helper for the pre-job image pull instead.
GitLab Runner supports Docker credential-helper configuration for ECR registries. On self-managed runners, put the helper configuration in the runner’s effective Docker configuration and give the runner an AWS credential source. Then the runner can obtain authentication for images it pulls before the CI script begins. For jobs that perform a push later, a fresh login during the job remains a simple operational choice.
Refresh ECR login inside AWS CodeBuild
AWS CodeBuild projects may build and push Docker images to ECR as part of a buildspec. The build environment receives IAM credentials through its service role, so hardcoded AWS access keys are normally unnecessary. The service role still needs ECR permissions, and Docker access must be configured for the build environment. The project’s Docker build mode and image determine whether privileged mode is required.
Perform ECR login during the build, close to the Docker operation. In a typical buildspec, the pre_build phase obtains the token and authenticates to the target registry, followed by build and push commands. For unusually long builds, repeat the login just before push rather than relying on a token acquired many hours earlier. Review the specific build image’s tooling to ensure Docker and AWS CLI are installed.
version: 0.2
phases:
pre_build:
commands:
- REGISTRY="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
- aws ecr get-login-password --region "$AWS_DEFAULT_REGION" | docker login --username AWS --password-stdin "$REGISTRY"
build:
commands:
- docker build -t "$REGISTRY/booking-api:$CODEBUILD_RESOLVED_SOURCE_VERSION" .
post_build:
commands:
- aws ecr get-login-password --region "$AWS_DEFAULT_REGION" | docker login --username AWS --password-stdin "$REGISTRY"
- docker push "$REGISTRY/booking-api:$CODEBUILD_RESOLVED_SOURCE_VERSION"
The example uses the source version as a tag; adapt it if your source identifier contains characters unsuitable for Docker tags or is not available. Your ECR repository must exist and the CodeBuild service role must have permission to push. If get-login-password fails with AccessDenied, inspect that role. If login works but push fails, inspect repository policies and the exact target URI.
CodeBuild can also pull its own build environment image from ECR in supported configurations. That image is fetched before buildspec commands execute, so a login in pre_build cannot resolve a project image-pull failure. Review the CodeBuild project service role, image source settings, and applicable ECR repository policy for that earlier stage. This distinction prevents endless edits to a buildspec that is not even reached.
Fix Kubernetes imagePullSecrets that contain expired ECR tokens
Kubernetes can use a secret of type kubernetes.io/dockerconfigjson or a registry secret created with kubectl create secret docker-registry. If you create that secret using a short-lived ECR password, the stored value will not refresh itself automatically. A pod can run for hours after a successful pull, then a replacement pod can fail to fetch the same image because its saved credentials expired. This often surfaces as ImagePullBackOff or ErrImagePull.
Check the pod events and secret reference before changing the deployment. Use kubectl describe pod to inspect pull failures and confirm that the pod or service account references the intended imagePullSecrets entry. A missing or wrong-namespace secret is different from an expired token. If the registry hostname in the secret differs from the image hostname, Kubernetes may not find the credential at all.
kubectl describe pod booking-api-abc123 -n production
kubectl get secret ecr-pull -n production
kubectl get serviceaccount default -n production -o yaml
For a generic cluster that genuinely relies on static pull secrets, rotate the secret with a fresh ECR token before it expires. The example below runs from a trusted administrative shell with Kubernetes access and AWS permission, not from within an ordinary application pod. Keep registry passwords out of the repository and out of CI logs. A production rotation should use secure automation and least-privilege access to both systems.
ECR_PASSWORD="$(aws ecr get-login-password --region us-east-1)"
kubectl create secret docker-registry ecr-pull \
--docker-server=123456789012.dkr.ecr.us-east-1.amazonaws.com \
--docker-username=AWS \
--docker-password="$ECR_PASSWORD" \
--namespace production \
--dry-run=client -o yaml | kubectl apply -f -
unset ECR_PASSWORD
For EKS worker nodes, prefer the supported node or kubelet credential-provider integration where it fits your architecture, rather than building a recurring secret-rotation job unnecessarily. Managed node setups commonly rely on node IAM permissions to pull private ECR images. The credentials used for pulling an image are part of node runtime behavior, not the same thing as AWS credentials attached to the application container through its service account. Determine which identity actually performs the pull before changing permissions.
Jake: "The pod ran all week, but its replacement cannot start. Did the image disappear?"
Ethan: "Possibly not. The running pod had already pulled its image, while the new pod needs fresh registry access. An expired pull secret can break only the new start."
- Describe the failing pod and record the image-pull event without printing registry credentials.
- Inspect the pod namespace, referenced imagePullSecrets, and exact image registry hostname.
- Decide whether the node already has a supported ECR credential-provider integration.
- If this cluster relies on a static secret, rotate it securely and confirm the pod can pull the requested image.
Do not confuse ECR Public and private ECR login
Private ECR registries normally use an address like 123456789012.dkr.ecr.us-east-1.amazonaws.com. Public ECR uses public.ecr.aws, and the AWS CLI command is different. If you paste a private ECR login command against a public hostname, you are troubleshooting the wrong flow. Identify the image address first.
For ECR Public, use aws ecr-public get-login-password --region us-east-1 with docker login to public.ecr.aws. Public registry login uses its own AWS permissions and the public ECR endpoint requirements. An authenticated pull can fail later when the public ECR token expires. Some public images also support unauthenticated pulls, so logging out of an expired cached public token may restore access where anonymous pulling is allowed.
aws ecr-public get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin public.ecr.aws
# For an image eligible for anonymous pull, remove stale public login:
docker logout public.ecr.aws
The anonymous-pull workaround has no place on a private ECR repository. Private access still requires valid credentials and appropriate IAM authorization. Likewise, a credential helper entry for a private registry hostname does not automatically cover public.ecr.aws unless you configure that hostname too. Keep both registry types explicit in your Docker configuration.
If you work with accounts in different AWS partitions, use the registry hostname format appropriate to that partition rather than copying the commercial partition example blindly. The account ID, Region, and suffix are part of the registry identity. A password from one regional ECR authentication endpoint will not repair a mismatch in the actual repository address. This matters particularly in scripts that build image URLs from environment variables.
A worked twelve-hour timeline for a failed release
Consider a hypothetical CI system that logs in at 8:00 a.m. and retains the same Docker configuration for later tasks. It pushes successfully at 9:00 a.m. A separate release task reuses that token at 9:00 p.m., thirteen hours after the original login. Because the token’s 12-hour validity has ended, the release task can fail even if the build and ECR repository settings are unchanged.
The solution is not to increase an ECR quota or change the repository name. Add an authentication step near the later push or configure the ECR helper on that runner. A token created at 8:00 a.m. is not suitable for unlimited later use, and the fact that an earlier push worked proves only that it had usable authorization at the earlier time. This example uses clock times to illustrate the documented lifetime; it is not a claim of a reproduced failure.
| Illustrative event | Time | Credential situation |
|---|---|---|
| Runner performs ECR login | 8:00 a.m. | Fresh ECR token |
| Initial image push | 9:00 a.m. | Within token lifetime |
| Same runner starts late push | 9:00 p.m. | Original 12-hour token expired |
| Runner retrieves new token | 9:01 p.m. | New authorization window begins |
The cost of this fix is primarily operational: a short authentication step compared with a failed deployment. ECR token generation itself is not a separately priced compute instance. Your container registry storage, image transfers, CI resources, and other AWS services can still generate charges under their own pricing. There is no ECR token-renewal fee to budget for, and no fixed bill for this scenario.
For workloads that operate longer than twelve hours, align authentication refresh with the actual push or pull boundary. Long builds can run every compile command without a registry credential, but the eventual upload requires a valid one. A repeat login before upload is simple; the credential helper is attractive when operations occur unpredictably. Pick based on how the system runs, not a universal timer.
What to inspect when a fresh login does not solve it
A fresh login that returns Login Succeeded is a useful diagnostic milestone, but the next Docker error may point elsewhere. Compare the image repository path and registry account, then confirm the repository exists. If the push fails with a 403, check the caller’s ECR actions, any destination repository policy, and explicit-deny restrictions. A token refresh cannot manufacture authorization that the principal does not possess.
If the AWS CLI itself reports invalid or expired credentials, repair the source session before involving Docker. For an SSO profile, use the appropriate AWS SSO login workflow. For assumed roles, confirm the process can obtain current role credentials. For a CI system, inspect how its identity is issued and whether its session remains valid at the point where the job retrieves the ECR password.
If the helper fails, inspect the helper executable and effective Docker configuration. A configuration file under your normal home directory does not control a Docker invocation launched with a different account or explicit DOCKER_CONFIG. Registry hostnames in credHelpers should match the image hostname, and old manual tokens should be cleared when migrating to the helper. Review sanitized client and helper logs without exposing actual authorization tokens.
If Kubernetes cannot pull, inspect pod events and the node’s image-pull permissions rather than changing the application’s runtime IAM role automatically. EKS nodes and generic Kubernetes clusters can follow different authentication patterns. A secret that exists in the wrong namespace does not help the pod that needs it. Document the cluster type, image address, service account, node configuration, and exact error before opening a support case.
Collect useful evidence before escalating an ECR authentication failure
When authentication remains broken, collect the full sanitized error, UTC timestamp, AWS Region, account ID, registry hostname, and operation that failed. Record whether the failure happened during Docker login, push, pull, CI image setup, or a Kubernetes pod start. These distinctions locate the failing layer. A support request saying only “ECR is broken” forces somebody else to rediscover the basic context.
Capture aws sts get-caller-identity output for the affected process and note whether it uses an IAM role, AWS profile, or workload identity. Include the fact that a fresh login was attempted, and keep the actual output of get-login-password out of the case. For a permission-denied error, identify the repository and principal. For a helper failure, describe the helper configuration keys and installation version without disclosing stored credentials.
For CI, attach a redacted section of the workflow or buildspec showing where AWS credentials are configured and where Docker login happens. For Kubernetes, include pod events, relevant imagePullSecrets names, and node authentication architecture. Leave the raw contents of a registry secret or Docker auths value out of the attachment. Sensitive credentials are not required to diagnose a mismatch between hostname, Region, and identity.
After an incident, choose a prevention measure that matches the original failure. Interactive developers benefit from the ECR helper. Ephemeral runners benefit from authenticating in each job. Kubernetes clusters benefit from a supported image credential-provider integration or securely managed secret rotation where necessary. The best fix is the one that keeps credentials fresh at the moment Docker actually needs them.
Frequently asked questions about ECR authorization and Docker login
Why does AWS ECR say your authorization token has expired?
An ECR authorization token has a 12-hour lifetime. Docker may be reusing a password from an earlier login after that validity period ended. Obtain a new password with aws ecr get-login-password and log in to the exact private ECR registry.
How do I fix aws ecr your authorization token has expired reauthenticate?
Run aws ecr get-login-password for the repository Region and pipe it to docker login with username AWS and --password-stdin. Check that the registry hostname matches the image you push or pull. If the AWS CLI fails, refresh your underlying AWS credentials first.
What does ecr get-login-password do?
The AWS CLI requests an ECR authorization token and outputs the password portion for a container client. It does not push an image or grant additional IAM permissions. Pass the password directly to docker login through standard input.
How long does an ECR Docker login last?
The ECR authorization token is valid for 12 hours. Your AWS session and Docker credential-storage behavior are separate concerns. For recurring work, use a supported credential helper or a fresh login at each CI job.
How do I docker login to ECR on Windows PowerShell?
Run aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin REGISTRY, replacing REGISTRY with the real ECR hostname. Make sure AWS CLI v2 and Docker Desktop are ready. Use the bare host without https://.
How do I docker login to ECR on macOS or Linux?
Use aws ecr get-login-password --region REGION piped to docker login --username AWS --password-stdin REGISTRY. Confirm your AWS principal with aws sts get-caller-identity. Run the later Docker command under the same effective Docker configuration or use the ECR credential helper.
Why does docker push report no basic auth credentials with ECR?
Docker may lack a usable credential for the exact registry hostname, or a previously saved token may have expired. Log in again with a current ECR password and confirm the account and Region. If the error persists, inspect Docker config, credential helpers, and repository permissions.
Does the ECR credential helper eliminate docker login?
Yes, once properly installed and configured, Docker can ask the helper for current ECR authorization as needed. The underlying AWS credentials must still be available and authorized. The helper does not make tokens permanent or bypass expired AWS sessions.
Where is the Docker ECR credential helper configured?
Use credHelpers in Docker config.json for the relevant ECR hostname, with the value ecr-login. Docker locates docker-credential-ecr-login on the effective PATH. Configuration is user-specific unless a runner or service account has its own setup.
Why does ECR login work but docker push returns 403?
A successful login does not guarantee permission to upload layers or put an image in the target repository. Verify your role, the destination account, the ECR repository policy, and the Region. The repository may also be missing or the image tag may point elsewhere.
Do I need ECR login in every GitHub Actions job?
Each job that runs Docker against private ECR needs usable registry credentials in its runner environment. Use AWS identity configuration and the ECR login action in the job that pushes or pulls. A login in another job is not automatically shared.
How do I use ECR in GitLab CI without expired credentials?
Have the job obtain AWS credentials and run aws ecr get-login-password immediately before Docker needs the registry. For an ECR image used as the GitLab job image itself, configure runner-level authentication because that pull happens before the script. A runner-installed ECR helper can support that setup.
How do I refresh ECR credentials in CodeBuild?
Use the CodeBuild service role and execute aws ecr get-login-password during the buildspec before pushing. In very long builds, refresh near the final upload. An ECR image used as the CodeBuild environment is pulled before the buildspec starts and needs its own project-level access.
Why do Kubernetes ECR imagePullSecrets stop working?
A secret containing a static ECR token can outlive the token’s 12-hour validity. New pods then fail to pull even if existing pods are running. Use a supported node image credential provider or securely rotate the pull secret before expiration.
Is ECR Public login the same as private ECR login?
No. ECR Public uses aws ecr-public get-login-password with us-east-1 and the public.ecr.aws registry. Private ECR uses aws ecr get-login-password with the repository Region and its private registry hostname. Public anonymous pulls may also be possible for eligible images.
What should I check if a new ECR token still does not work?
Confirm the current AWS identity, target registry hostname, Region, and ECR repository permissions. Inspect the Docker config used by the actual process and clear a stale manual login if it blocks the ECR helper. In CI or Kubernetes, verify which environment or node obtains image credentials.
If the old token held up a release, the fix can be smaller than the failure first suggests. Start with a fresh login to the exact registry; when you need a durable workflow, move renewal into the credential helper or the job that performs the push. Keep your AWS identity and repository policies narrowly scoped, and your next late-night deployment should be easier to understand even when the registry rejects a request.
📌 If you keep one line from this page
ECR tokens last 12 hours: authenticate to the exact registry when Docker needs access, or let the credential helper obtain a fresh token.
Revision note. Written October 15, 2026, with the 12-hour token and the credential helper packages for Amazon Linux 2023, Debian and Homebrew. Make hay while the sun shines: push while the token is fresh, or let the helper fetch a new one.