This error occurs when the Docker daemon cannot authenticate with AWS CloudWatch Logs. The awslogs logging driver requires AWS credentials to be provided directly to the Docker daemon, not to individual containers.
The "failed to get awslogs credentials" error indicates that Docker's awslogs logging driver cannot find valid AWS credentials to authenticate with Amazon CloudWatch Logs. This is a common source of confusion because the credentials must be available to the Docker daemon itself, not to the container being run. When you configure a container to use the awslogs logging driver, the Docker daemon (not the container) is responsible for sending logs to CloudWatch. This means passing AWS credentials via environment variables to `docker run` or in your application code will not work. The daemon process needs direct access to credentials through one of three methods: environment variables set for the daemon service, the shared credentials file (~/.aws/credentials of the root user), or an EC2 instance profile. This error commonly appears when developers test locally with Docker Desktop, run Docker on on-premises servers without instance profiles, or misconfigure credential paths on Linux systems where the Docker daemon runs as a system service.
First, confirm that AWS credentials are properly configured on your system:
aws sts get-caller-identityThis should return your AWS account ID and ARN. If this fails, configure credentials first:
aws configureNote: Even if this works, it doesn't mean Docker can access these credentials. The Docker daemon runs as a separate service and may not have access to your user's credentials.
On Linux systems using systemd, create a drop-in configuration file to pass AWS credentials to the Docker daemon:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/aws-credentials.confAdd the following content:
[Service]
Environment="AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY"
Environment="AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY"
Environment="AWS_DEFAULT_REGION=us-east-1"Then reload systemd and restart Docker:
sudo systemctl daemon-reload
sudo systemctl restart dockerSecurity note: This stores credentials in a system file. Consider using instance profiles or other secure methods for production environments.
The Docker daemon can read credentials from the root user's AWS credentials file. Create or copy credentials to /root/.aws/credentials:
sudo mkdir -p /root/.aws
sudo nano /root/.aws/credentialsAdd your credentials:
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
region = us-east-1Set proper permissions:
sudo chmod 600 /root/.aws/credentials
sudo chmod 700 /root/.awsRestart Docker to pick up the credentials:
sudo systemctl restart dockerIf running on EC2, the best practice is to use an instance profile with an IAM role. First, create an IAM role with this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}Attach the role to your EC2 instance:
1. Go to EC2 Console > Instances
2. Select your instance
3. Actions > Security > Modify IAM role
4. Select or create an instance profile with the above policy
The Docker daemon automatically detects and uses instance profile credentials. No restart is needed.
For servers outside AWS, disable EC2 metadata lookup to prevent timeout delays and ensure file-based credentials are used:
Using Docker run:
docker run \
--log-driver=awslogs \
--log-opt awslogs-region=us-east-1 \
--log-opt awslogs-group=my-log-group \
-e AWS_EC2_METADATA_DISABLED=true \
your-imageUsing Docker Compose:
version: '3.8'
services:
app:
image: your-image
environment:
- AWS_EC2_METADATA_DISABLED=true
logging:
driver: awslogs
options:
awslogs-region: us-east-1
awslogs-group: my-log-group
awslogs-stream: my-log-streamEnsure the Docker daemon has credentials configured via the systemd or root credentials file methods described above.
Docker Desktop runs in a VM, making credential access more complex. There are several approaches:
Option 1: Mount credentials volume (Docker Compose)
version: '3.8'
services:
app:
image: your-image
volumes:
- ~/.aws:/root/.aws:ro
environment:
- AWS_EC2_METADATA_DISABLED=true
logging:
driver: awslogs
options:
awslogs-region: us-east-1
awslogs-group: my-log-groupOption 2: Use a log aggregator container
Instead of the awslogs driver, use a sidecar container that forwards logs to CloudWatch and can receive credentials normally.
Option 3: Local development alternative
For local development, consider using the default json-file driver and only enabling awslogs in production:
logging:
driver: "${LOG_DRIVER:-json-file}"
options:
awslogs-region: us-east-1
awslogs-group: my-log-groupThe awslogs driver requires the log group to exist unless you enable automatic creation. Check if your log group exists:
aws logs describe-log-groups --log-group-name-prefix my-log-groupIf it doesn't exist, create it:
aws logs create-log-group --log-group-name my-log-group --region us-east-1Or enable automatic creation with the awslogs-create-group option:
docker run \
--log-driver=awslogs \
--log-opt awslogs-region=us-east-1 \
--log-opt awslogs-group=my-log-group \
--log-opt awslogs-create-group=true \
your-imageNote: Using awslogs-create-group requires the logs:CreateLogGroup IAM permission.
Run a simple container to verify awslogs is working:
docker run --rm \
--log-driver=awslogs \
--log-opt awslogs-region=us-east-1 \
--log-opt awslogs-group=test-log-group \
--log-opt awslogs-stream=test-stream \
alpine echo "Hello CloudWatch"If successful, verify the log appeared in CloudWatch:
aws logs get-log-events \
--log-group-name test-log-group \
--log-stream-name test-stream \
--region us-east-1You should see "Hello CloudWatch" in the events.
Understanding credential resolution order: The Docker daemon checks for credentials in this order: (1) Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN), (2) Shared credentials file (~/.aws/credentials of the user running Docker, typically root), (3) EC2 instance profile. The daemon uses the first valid credentials found.
Session tokens and temporary credentials: If using AWS SSO, assumed roles, or temporary credentials, you must also include AWS_SESSION_TOKEN. These credentials expire and must be refreshed. For long-running Docker daemons, instance profiles are preferred as they automatically refresh credentials.
Region detection: On EC2 instances, the awslogs driver automatically detects the region from instance metadata. On other systems, you must specify awslogs-region explicitly. Without a region, you'll get a different error about missing region configuration.
Debugging credential issues: Enable Docker daemon debug logging to see credential resolution attempts:
# Edit /etc/docker/daemon.json
{
"debug": true
}
# Restart Docker and check logs
sudo journalctl -u docker -fECS and Fargate considerations: When running on ECS or Fargate, the task execution role provides credentials automatically. You don't need to configure credentials manually - just ensure the task execution role has the required CloudWatch Logs permissions.
Container-level credential workarounds: Some users work around the daemon credential requirement by running a log forwarder container (like Fluentd or Fluent Bit) that receives logs from other containers via a shared volume or network and forwards them to CloudWatch. This approach lets you pass credentials to the forwarder container normally.
Credential security best practices:
- Never commit credentials to source control
- Use instance profiles or ECS task roles in production
- Rotate credentials regularly
- Use IAM roles with minimal required permissions
- Consider AWS Secrets Manager for credential rotation
Alternative logging solutions: If awslogs proves problematic, consider:
- Fluent Bit with CloudWatch output plugin
- CloudWatch Agent running on the host
- Third-party log aggregation services that support Docker natively
image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub