CloudWatch "The Specified Log Group Does Not Exist" (ResourceNotFoundException): Every Cause and the Fix (Lambda, ECS, CLI, CloudFormation)

Logeshwaran
—

"The specified log group does not exist" is CloudWatch Logs telling you it looked for one exact name, in one AWS Region, in one account, and found nothing. Most of the time the logs are fine and you are looking in the wrong place: the AWS CLI is pointed at a different Region, a different profile or account, or the name differs by a single letter or a capital, because log group names are case-sensitive. The rest of the time, the log group was simply never created. Lambda only creates /aws/lambda/<function-name> the first time the function runs, so a brand-new function has no log group at all. ECS does not create one unless you set awslogs-create-group to "true", which defaults to false. And the strangest case of all: on Windows, Git Bash silently rewrites /aws/lambda/my-function into C:/Program Files/Git/aws/lambda/my-function before the AWS CLI ever sees it. Every version of the error, from the CLI to Fargate to CloudFormation, has a fix below.

Ethan built the booking system for Jake's phone repair shop on AWS: a small Lambda function takes online bookings, and a container on ECS sends the confirmation texts. On Monday a customer said her booking never arrived. Jake, who had learned exactly one AWS command from Ethan, opened a terminal and typed aws logs tail /aws/lambda/booking-api. The answer came back in red: "The specified log group does not exist." He called Ethan, half convinced the whole system had been deleted. "It hasn't," Ethan said, before even looking. "You're standing in the wrong shop." This page walks through what the error really means, the one-minute check that finds the log group, and the fix for every place the message turns up: the AWS CLI and Python, Lambda, Lambda@Edge, ECS and Fargate, CloudFormation, CDK and Terraform, API Gateway, the CloudWatch agent and Windows Git Bash.

⚡ Quick Answer

• From the AWS CLI or Python? → Almost always the wrong Region, profile or spelling. Run aws logs describe-log-groups --log-group-name-prefix /aws/lambda/ with the right --region. The one-minute check.

• A new Lambda function? → Its log group appears only after the first invocation, and only if the role allows logs:CreateLogGroup. Lambda fix.

• ECS or Fargate task won't start? → Create the log group, or set "awslogs-create-group": "true" and allow logs:CreateLogGroup on the task execution role. ECS fix.

• CloudFormation, CDK or Terraform? → Declare the log group yourself and reference it, so it exists before the filter or function that needs it. Template fix.

• Windows Git Bash? → Prefix the command with MSYS_NO_PATHCONV=1. Why.

Nothing on this page deletes anything. Every check is read-only until you choose to create a log group.

New to AWS logging? Our plain-English guide to what Amazon CloudWatch is explains log groups and log streams from zero. This page starts gently too.

🧭 NEW HERE? READ THESE FIRST

New to AWS? These five pages make this error, and the fixes below, much easier to follow:

📌 Bookmark this; the one-minute check works for every version of this error.

What "The specified log group does not exist" really means

CloudWatch Logs files your logs in two levels. A log group is a labeled drawer, usually one per application or function, such as /aws/lambda/booking-api or /ecs/sms-sender. Inside it, log streams are the folders, one per running copy of your code, each holding the actual lines. When anything reads or writes logs, it names the drawer first. If the drawer cannot be found, the request stops there, with this error.

Here is the part that trips everyone up. "Cannot be found" depends on three things at once, and all three must match:

  • The exact name. Log group names can be up to 512 characters of letters, numbers, underscore, hyphen, forward slash, period and the number sign, and they are case-sensitive. /aws/lambda/Booking-API and /aws/lambda/booking-api are two different drawers.
  • The Region. Log groups live in one AWS Region. A log group in US East (Ohio) is invisible to a request sent to US East (N. Virginia), even from the same account.
  • The account. A log group belongs to one AWS account. If your terminal is signed in to the development account and the function runs in production, the drawer is in a different building.

So the error has only two real meanings. Either the log group exists and you are asking the wrong Region, account or spelling, or it does not exist yet because nothing ever created it. The first is far more common, and it takes a minute to prove.

Who creates the log group, and when

The second meaning, "it was never created," depends on which service was supposed to create it. Each one has its own rule:

ServiceLog group nameWho creates it, and whenPermission needed
Lambda/aws/lambda/<function-name>Created automatically on the first invocationlogs:CreateLogGroup on the execution role
Lambda, custom groupAny name not starting with aws/The console creates it if missing; with the CLI or API, create it yourselflogs:PutLogEvents on the execution role
Lambda@Edge/aws/lambda/us-east-1.<FunctionName>Created in each Region where the function runsAs for Lambda
ECS (awslogs driver)Whatever awslogs-group saysNever, unless awslogs-create-group is "true"logs:CreateLogGroup on the task execution role
API Gateway execution logsAPI-Gateway-Execution-Logs_{rest-api-id}/{stage-name}After logging is switched on for the stageA CloudWatch role ARN in that Region's account settings
CloudWatch agentlog_group_name, or the file pathThe agent creates it when it starts sendinglogs:CreateLogGroup (in CloudWatchAgentServerPolicy)
CloudFormation, CDK, TerraformWhatever you declareOnly if the template declares the log groupThe deploying role

Jake: "So it's like asking the Ohio branch for a customer file that's kept at the Virginia branch?"

Ethan: "Exactly. The clerk in Ohio isn't lying when she says 'no such file.' She just doesn't have it. The fix is to call the right branch, not to make a new file."

Find the log group first: the one-minute check

Before you create anything, find out whether the log group already exists somewhere. Creating a second, empty log group in the wrong Region makes the error go away and hides the real problem, which is how logs end up split across two drawers for months.

Step 1: see which Region and account your terminal is using.

aws configure get region
aws sts get-caller-identity --query Account --output text

The first command prints the Region from your current profile; it prints nothing, and exits with code 1, if the Region comes only from an environment variable or nowhere at all. The second prints the 12-digit account number you are signed in to. Compare both with where the function or container actually runs, which the Lambda or ECS console shows in its top bar.

Step 2: list the log groups that start with the name you expect, in the Region you expect.

aws logs describe-log-groups --region us-east-2 \
  --log-group-name-prefix /aws/lambda/booking \
  --query 'logGroups[].logGroupName' --output text

Use a shorter prefix than the full name on purpose. If /aws/lambda/booking lists /aws/lambda/booking-api-prod, the problem was the name. If it lists nothing at all for a prefix where you expect many log groups, you are almost certainly in the wrong Region or account.

Step 3: search by any part of the name. When you are not sure how the name starts, --log-group-name-pattern matches any part of it:

aws logs describe-log-groups --region us-east-2 \
  --log-group-name-pattern booking \
  --query 'logGroups[].logGroupName' --output text

That search is case-sensitive as well: a pattern of booking finds /aws/lambda/booking-api but not /aws/lambda/Booking-API. Try the capitalization your team uses. The prefix and pattern options cannot be combined in one call.

Step 4: check the other Regions you use. If the log group is not where you expected, sweep the likely Regions in one go:

for r in us-east-1 us-east-2 us-west-2 eu-west-1 ap-south-1; do
  n=$(aws logs describe-log-groups --region "$r" \
      --log-group-name-prefix /aws/lambda/booking-api \
      --query 'length(logGroups)' --output text)
  [ "$n" != "0" ] && echo "$r: $n"
done

Edit the list to the Regions your company uses. Whichever Region prints a number is where the log group lives; rerun your original command with that --region and the error disappears.

That was exactly Jake's problem. His laptop's default Region was us-east-1; Ethan had built the shop's system in us-east-2, closer to the shop. aws logs tail /aws/lambda/booking-api --region us-east-2 showed the missing booking at once: the customer had typed her phone number with a letter in it.

Every version of the message, and where it comes from

The same five words appear in very different places, wrapped in different text. Match yours to the table, then jump to its section.

Where you see itWhat the full message looks likeGo to
AWS CLI aws logs tailAn error occurred (ResourceNotFoundException) when calling the FilterLogEvents operation: The specified log group does not exist.CLI and Python
AWS CLI get-log-eventsAn error occurred (ResourceNotFoundException) when calling the GetLogEvents operation: The specified log group does not exist.CLI and Python
Python (boto3), Zappa and similar toolsbotocore.errorfactory.ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the DescribeLogStreams operation: The specified log group does not exist.CLI and Python
ECS on EC2CannotStartContainerError: Error response from daemon: failed to initialize logging driver: failed to create Cloudwatch log stream: ResourceNotFoundException: The specified log group does not exist. status code: 400ECS
ECS on FargateResourceInitializationError: failed to validate logger args: create stream has been retried 1 times: failed to create Cloudwatch log stream: ResourceNotFoundException: The specified log group does not exist. : exit status 1ECS
CloudFormationResource handler returned message: "The specified log group does not exist. (Service: CloudWatchLogs, Status Code: 400, ...)" ... HandlerErrorCode: InvalidRequestTemplates
CDK deployCREATE_FAILED | AWS::Logs::MetricFilter | ... The specified log group does not existTemplates
CloudWatch consoleThere was an error filtering log events. The specified log group does not exist.Other services

Newer releases of AWS CLI version 2 print the same message with aws: [ERROR]: in front of it, and the command exits with code 254, which means the request reached AWS and AWS answered with an error. In scripts, that exit code is how you tell "AWS said no" apart from a typo in the command itself.

Lambda: the log group appears only after the first invocation

This is the cause that surprises people most. When you create a Lambda function, no log group is created with it. CloudWatch creates /aws/lambda/<function-name> the first time the function is invoked, and only if the function's execution role is allowed to. So all of these fail on a function that has never run:

  • aws logs tail /aws/lambda/my-new-function right after a deploy.
  • The "View CloudWatch logs" link in the Lambda console for a function nobody has tested yet.
  • A metric filter, subscription filter or retention policy created in the same deployment as the function, before its first run.

The fix, in order:

  1. Invoke the function once, from the Test tab in the Lambda console or with aws lambda invoke --function-name booking-api out.json and the right --region.
  2. Wait a few minutes. Logs can take 5 to 10 minutes to show up after an invocation, so an empty result right after a test is normal.
  3. Check the Region again. The log group is created in the function's Region, which is not always your terminal's default.
  4. Check the execution role if the group still never appears.

For that last step: Lambda needs three permissions to log: logs:CreateLogGroup, logs:CreateLogStream and logs:PutLogEvents. The AWS managed policy AWSLambdaBasicExecutionRole contains all three:

aws iam attach-role-policy --role-name booking-api-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Our guide to Lambda not logging to CloudWatch covers the permission side in depth, including roles that block logging on purpose.

Custom log groups for Lambda

A function can also send its logs to a log group you choose, through its logging configuration. Three rules apply, and each one produces this error when it is missed:

  • Through the console, Lambda creates the custom log group for you if no log group with that name exists, and it can add the logging permission to the role automatically.
  • Through the CLI or API, Lambda does not add the logs:PutLogEvents permission for you. Add it to the role yourself, or attach AWSLambdaBasicExecutionRole.
  • A custom log group name cannot begin with aws/. CloudWatch reserves that prefix, so Lambda cannot create the group, and your function's logs are simply not sent. Note the difference: the default names begin with /aws/, a leading slash, which is fine.
aws lambda update-function-configuration \
  --function-name booking-api \
  --logging-config LogGroup=/shop/booking-api

With a custom log group, the log stream names change too. They follow the pattern YYYY/MM/DD/<function_name>[<function_version>][<execution_environment_GUID>], so several functions can share one log group without mixing up their lines.

Renamed or redeployed functions

The log group is named after the function, so a function recreated under a new name gets a new, empty log group, while its old logs stay in the old one. If a dashboard, alarm or script still points at the old name, it fails with this error the moment the old group is deleted. Search with --log-group-name-pattern using a word both names share, and update whatever still points at the old name.

Lambda@Edge: the logs are in another Region, under another name

Lambda@Edge functions run in CloudFront locations around the world, and their logs follow them. Two details make the usual log group "not exist":

  • The name gets a prefix. The log group is /aws/lambda/us-east-1.<FunctionName>, with the Region where the function was created, which is us-east-1 for Lambda@Edge, added in front of the function name. Looking for /aws/lambda/<FunctionName> finds nothing.
  • The log streams are created in the Region where each request ran. A visitor in Mumbai produces logs in the Mumbai Region, under the same prefixed name. Looking only in us-east-1 misses them.

To see which Regions your edge function has run in, open the function's metrics in the CloudFront console; they are shown per Region, and from there you can open the logs for each one. With a custom log group name such as /MyLogGroup, Lambda@Edge does not add the prefix, and the name stays the same in every Region. Logs from edge functions are delivered on a best-effort basis, so a single missing request is not proof that something is broken.

ECS and Fargate: "failed to initialize logging driver"

On ECS, this error stops the container before your code even starts. The container's awslogs log driver tries to create a log stream inside the log group named in your task definition, the group is not there, and the task fails. On EC2 capacity you see CannotStartContainerError ... failed to initialize logging driver; on Fargate you see ResourceInitializationError: failed to validate logger args. Both end with "The specified log group does not exist."

The reason is a default that catches almost everyone: awslogs-create-group defaults to false. Unless you say otherwise, ECS expects the log group to exist already, and refuses to start the container when it does not. There are four common ways to land here:

  • The task definition was written by hand or copied from another project, and nobody created its log group.
  • The log group existed but was deleted, for example by a cleanup script or with an old CloudFormation stack. Running tasks keep going; the next task to start fails.
  • awslogs-region names a different Region from the one where the log group lives. ECS can send logs to any Region you choose, and the log group must exist in that Region.
  • awslogs-create-group is set to "true", but the task execution role lacks logs:CreateLogGroup, so ECS is not allowed to create it.

Fix 1: create the log group (fastest)

Read the exact group name and Region from the task definition's logConfiguration, then create it there:

aws logs create-log-group --log-group-name /ecs/sms-sender --region us-east-2
aws logs put-retention-policy --log-group-name /ecs/sms-sender --retention-in-days 30 --region us-east-2

The second line is optional but wise: a new log group keeps everything forever by default, and our guide to CloudWatch Logs costs shows how that bill grows. The next task the service starts finds its log group and runs. Tasks that already failed stay stopped; the service replaces them by itself.

Fix 2: let ECS create the log group

Set awslogs-create-group to the string "true" in the task definition, and give the task execution role permission to create log groups:

"logConfiguration": {
  "logDriver": "awslogs",
  "options": {
    "awslogs-group": "/ecs/sms-sender",
    "awslogs-region": "us-east-2",
    "awslogs-stream-prefix": "sms",
    "awslogs-create-group": "true"
  }
}
aws iam put-role-policy --role-name ecsTaskExecutionRole \
  --policy-name allow-create-log-group \
  --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"logs:CreateLogGroup","Resource":"*"}]}'

Register the new task definition revision and update the service to use it. The permission is the step people skip: the AWS managed task execution policy grants logs:CreateLogStream and logs:PutLogEvents, which is enough to write into an existing log group but not to create one. If you prefer a tighter policy, replace the "*" with the log group's ARN.

Fix 3: check the Region in the task definition

If the log group exists and the error continues, compare awslogs-region with the Region shown in the CloudWatch console where the log group lives. A task definition copied from a project in another Region keeps the old Region in this field, and ECS sends the logs exactly where it is told.

When an ECS task stops for any other reason, our guide to "Essential container in task exited" covers the rest of the stopped-task messages.

AWS CLI and Python: Region, profile and account

From a terminal or a script, this error almost never means the logs are gone. Here is what the same command does in the wrong Region and in the right one:

$ aws logs tail /aws/lambda/booking-api
An error occurred (ResourceNotFoundException) when calling the FilterLogEvents operation: The specified log group does not exist.

$ aws logs tail /aws/lambda/booking-api --region us-east-2
2026-10-12T09:14:03 ... START RequestId: ...

The --region option overrides everything else for that one command. The Region otherwise comes from your environment variables or your profile, which is why the same command can work on a colleague's laptop and fail on yours.

Profiles and accounts. If you work with several AWS accounts, your terminal's default profile may point at the wrong one. Add --profile to both the check and the command:

aws logs describe-log-groups --profile prod --region us-east-2 \
  --log-group-name-prefix /aws/lambda/booking

If a profile name itself is rejected, our guide to AWS CLI profiles explains how the config and credentials files fit together.

Cross-account monitoring. Teams that view several accounts' logs from one central monitoring account must identify a source account's log group by its full ARN, not its name. API calls such as GetLogEvents accept either a name or an ARN in logGroupIdentifier, but for a log group in a linked source account, only the ARN works.

Once you find it: reading the logs from the command line

With the right Region in hand, aws logs tail is the easiest way to read logs. It is part of AWS CLI version 2, reads every log stream in the group at once, and by default shows the last ten minutes:

# the last hour, one line per event
aws logs tail /aws/lambda/booking-api --region us-east-2 --since 1h --format short

# only lines containing ERROR, from the last day
aws logs tail /aws/lambda/booking-api --region us-east-2 --since 1d --filter-pattern ERROR

# keep watching, like tail -f on a server
aws logs tail /aws/lambda/booking-api --region us-east-2 --follow

--since takes values such as 30m, 1h or 2d. --follow keeps printing new events until you press Ctrl+C, which is the quickest way to watch a function while you test it. For searches across many log groups or longer periods, CloudWatch Logs Insights in the console is the better tool.

Python (boto3): catch it, or create the log group safely

In Python, the error arrives as ResourceNotFoundException on the client's exceptions. When your code owns the log group, a small helper creates it if it is missing and sets a retention period, without failing when it already exists:

import boto3

logs = boto3.client("logs", region_name="us-east-2")

def ensure_log_group(name, days=30):
    try:
        logs.create_log_group(logGroupName=name)
        print("created", name)
    except logs.exceptions.ResourceAlreadyExistsException:
        print("already there", name)
    logs.put_retention_policy(logGroupName=name, retentionInDays=days)

ensure_log_group("/shop/sms-sender")

try:
    logs.get_log_events(logGroupName="/shop/missing", logStreamName="x")
except logs.exceptions.ResourceNotFoundException as e:
    print(e.response["Error"]["Code"], "-", e.response["Error"]["Message"])

Run twice, the helper prints "created" and then "already there," and the last line prints ResourceNotFoundException - The specified log group does not exist. Set region_name explicitly, as above. A script that relies on the default Region will one day run on a machine with a different default and fail with exactly this error.

A related trap: aws logs create-log-group on a name that already exists fails with ResourceAlreadyExistsException ... The specified log group already exists. If you see that message right after this one, for the same name, you have proved the Region or account was the problem all along.

Windows Git Bash turns /aws/lambda into C:/Program Files/Git

This one looks like magic the first time. On Windows, in Git Bash (and in other MSYS-based shells), any command-line argument that begins with a forward slash is treated as a Unix path and converted to a Windows path before the program receives it. Git Bash's root folder is C:/Program Files/Git, so this:

aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name '...'

reaches the AWS CLI as a log group called C:/Program Files/Git/aws/lambda/my-function. The colon and the space are not allowed in a log group name, so the usual result is:

An error occurred (InvalidParameterException) when calling the GetLogEvents operation: 1 validation error detected: Value 'C:/Program Files/Git/aws/lambda/my-function' at 'logGroupName' failed to satisfy constraint: Member must satisfy regular expression pattern: [.-_/#A-Za-z0-9]+

The fix is to switch the conversion off for that command:

MSYS_NO_PATHCONV=1 aws logs tail /aws/lambda/my-function --region us-east-2

Or run the command from PowerShell or Command Prompt, which leave the slash alone. One more Git Bash catch: inside double quotes, $LATEST in a Lambda log stream name such as 2026/10/12/[$LATEST]abc123 is read as an empty variable. Use single quotes around the stream name, or write \$LATEST; otherwise the name reaches AWS without $LATEST in it, and the request fails with a ResourceNotFoundException because nothing has that shortened name.

CloudFormation, CDK and Terraform: create the log group before anything uses it

Infrastructure code hits this error for one reason: a resource that needs the log group is created before the log group exists. The classic example is a metric filter or subscription filter on a Lambda function's log group, deployed together with the function. The function has never run, so its log group does not exist yet, and the filter fails with CREATE_FAILED.

The fix is the same in every tool: declare the log group yourself, with the exact name the service expects, and reference it, so the tool knows the order.

CloudFormation

CloudFormation works out the order from references. If resource A uses !Ref, !GetAtt or !Sub pointing at resource B, B is created first. A log group name typed as plain text is just a string, with no reference, so CloudFormation may create both at the same moment. Declare the log group and point at it:

Resources:
  BookingLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: /aws/lambda/booking-api
      RetentionInDays: 30

  BookingErrors:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref BookingLogGroup
      FilterPattern: '"ERROR"'
      MetricTransformations:
        - MetricName: BookingErrors
          MetricNamespace: Shop
          MetricValue: "1"

For a log group the function itself writes to, add DependsOn: BookingLogGroup to the function, so the group exists before the first invocation. If a stack fails on this error and rolls back, our guide to ROLLBACK_COMPLETE explains how to clean up before you deploy again.

CDK

In CDK, LogGroup.fromLogGroupName(...) only refers to a name; it creates nothing. When the function is new, create the log group explicitly with new LogGroup(this, "LogGroup", { logGroupName: "/aws/lambda/booking-api" }), and use that object for the metric filter, so CDK orders the resources correctly.

Terraform

Terraform's own Lambda example does exactly this: an aws_cloudwatch_log_group named /aws/lambda/${var.function_name} with a retention period, and a depends_on on the function so the log group is created first:

resource "aws_cloudwatch_log_group" "booking" {
  name              = "/aws/lambda/booking-api"
  retention_in_days = 30
}

resource "aws_lambda_function" "booking" {
  function_name = "booking-api"
  # ... role, runtime, handler, filename ...
  depends_on    = [aws_cloudwatch_log_group.booking]
}

Owning the log group in code has a second benefit: you choose the retention period instead of inheriting "never expire," and the group survives a function being replaced. If Terraform itself cannot reach its state, our guide to the Terraform S3 backend Access Denied error covers that separate problem.

API Gateway, the CloudWatch agent, databases and the console

API Gateway execution logs

REST API execution logs go to a log group named API-Gateway-Execution-Logs_{rest-api-id}/{stage-name}, which appears only after logging is switched on for the stage and requests arrive. Switching it on needs an IAM role that API Gateway can use to write logs, set as the cloudWatchRoleArn in the account settings, with the AmazonAPIGatewayPushToCloudWatchLogs managed policy attached. That setting must be made separately in each Region, so an API in a second Region can be missing its log group even though the first one logs perfectly. Access logs are different: for those, you create the log group yourself and give API Gateway its ARN.

The CloudWatch agent

The CloudWatch agent on EC2 or on-premises servers creates its log groups itself, and the CloudWatchAgentServerPolicy managed policy includes logs:CreateLogGroup for exactly that reason. If you wrote a tighter policy without it, the agent cannot create the group. Two naming details catch people: when log_group_name is left out, the agent uses the file path up to the final dot as the log group name, so /tmp/TestLogFile.log.2017-07-11-14 becomes a log group called /tmp/TestLogFile.log; and variables such as {instance_id} or {hostname} in the name create a separate log group per machine, which is easy to search for under the wrong name.

RDS, Neptune and other databases

Database logs reach CloudWatch only after you switch on log exports for that database. Until then, the console's link to the logs can open the CloudWatch page and show "There was an error filtering log events. The specified log group does not exist." Turn on the export for the log type you want in the database's settings, apply the change, and the log group appears once logs start flowing.

The CloudWatch console

In the console, the Region selector in the top bar decides which log groups you see. A link from another service sometimes opens CloudWatch in your last-used Region rather than the service's. If a log group you know exists shows this error, look at the Region in the top bar before anything else.

"The specified log stream does not exist": the sibling error

Once the log group is found, the next error people meet is its sibling: An error occurred (ResourceNotFoundException) when calling the GetLogEvents operation: The specified log stream does not exist. The drawer is right; the folder name is wrong. The usual reasons:

  • The stream name was copied wrong. Lambda stream names such as 2026/10/12/[$LATEST]4e288b653df8409e977aa4093303761b are long and easy to break. List the real names first: aws logs describe-log-streams --log-group-name /aws/lambda/booking-api --order-by LastEventTime --descending --max-items 5 --region us-east-2.
  • The shell ate part of it. As in the Git Bash section, $LATEST inside double quotes disappears. Use single quotes.
  • You do not need a stream name at all. aws logs tail and filter-log-events read every stream in a log group, which is easier than hunting for one.

Stop it coming back: create, protect and keep your log groups

Most repeat cases come from log groups that appear and disappear on their own schedule. Three habits end that:

  1. Create log groups on purpose. Declare them in CloudFormation, CDK or Terraform, or with the Python helper above, rather than relying on the first invocation or awslogs-create-group. You also get to choose their retention.
  2. Turn on deletion protection for the ones that matter. CloudWatch Logs can now block every deletion of a log group until protection is switched off again. New log groups start without it.
  3. Set a retention period. By default, log events never expire. A retention period keeps the bill sane without deleting the log group itself, which is the thing that causes this error.
aws logs put-log-group-deletion-protection --region us-east-2 \
  --log-group-identifier /ecs/sms-sender --deletion-protection-enabled
aws logs put-retention-policy --region us-east-2 \
  --log-group-name /ecs/sms-sender --retention-in-days 30

Jake: "So locking the drawer is a thing now? Why isn't that the default?"

Ethan: "Same reason the shop's back door isn't welded shut. Sometimes you really do want to clear a drawer out. Lock the ones customers depend on, like bookings and texts, and leave the scratch ones alone."

Troubleshooting by symptom

It works on a colleague's laptop but not on mine

Different default Region or profile. Run aws configure get region and aws sts get-caller-identity on both machines and compare, then add --region and --profile explicitly.

The log group shows in the console, but the CLI says it does not exist

The console's Region selector and your CLI's Region differ, or the console is signed in to another account. Read the Region code from the console's top bar and pass it with --region.

A brand-new Lambda function has no log group

Normal. The log group is created on the first invocation. Invoke the function once, wait a few minutes, and check that its role allows logs:CreateLogGroup.

The Lambda function runs, but its log group never appears

The execution role cannot create log groups or write to them, or a custom log group name starts with aws/. Attach AWSLambdaBasicExecutionRole, and rename any custom group that uses the reserved prefix.

ECS tasks stop with "failed to initialize logging driver"

The task definition's log group does not exist in its awslogs-region. Create it there, or set awslogs-create-group to "true" and allow logs:CreateLogGroup on the task execution role.

It worked for months, then every new ECS task failed

Someone deleted the log group. Running tasks continue; new tasks cannot start. Recreate it with the same name and Region, then turn on deletion protection.

Lambda@Edge logs are nowhere

Look for /aws/lambda/us-east-1.<FunctionName>, in the Regions where requests actually ran. The CloudFront console shows them per Region.

"InvalidParameterException ... C:/Program Files/Git" on Windows

Git Bash converted the leading slash into a Windows path. Prefix the command with MSYS_NO_PATHCONV=1, or use PowerShell.

CloudFormation or CDK fails with CREATE_FAILED on a filter

The filter was created before the log group existed. Declare the log group in the template and reference it with !Ref, or create it explicitly in CDK.

The logs I need are in a different account

Switch with --profile, or in a cross-account monitoring setup, use the log group's full ARN instead of its name.

A capital letter is different

Log group names are case-sensitive. Search with --log-group-name-pattern using the lowercase and the capitalized form, and use the exact name it returns.

"The specified log group does not exist": frequently asked questions

What does "the specified log group does not exist" mean?

CloudWatch Logs could not find a log group with that exact name in the Region and account your request used. Usually the log group exists elsewhere: another Region, another account or a slightly different spelling. Otherwise it was never created, as with a Lambda function that has not run yet.

How do I fix ResourceNotFoundException: the specified log group does not exist?

First find the log group with aws logs describe-log-groups --log-group-name-prefix and the right --region and --profile. If it exists, rerun your command against that Region and account. If it does not, create it with aws logs create-log-group, or let the service create it.

Why does my Lambda function have no CloudWatch log group?

Lambda's log group, /aws/lambda/function-name, is created the first time the function is invoked, and only if the execution role allows logs:CreateLogGroup. Invoke it once, wait up to 10 minutes, and attach AWSLambdaBasicExecutionRole if the group still does not appear.

How do I fix "failed to initialize logging driver" in ECS?

The log group named in the task definition does not exist in its awslogs-region. Create it with aws logs create-log-group in that Region, or set awslogs-create-group to "true" and give the task execution role the logs:CreateLogGroup permission.

What does awslogs-create-group do?

It tells the awslogs log driver in ECS to create the log group if it is missing. It defaults to false, so without it the log group must already exist. It also needs logs:CreateLogGroup on the task execution role, which the standard execution policy does not include.

Why does "the specified log group does not exist" happen in CloudFormation?

A resource such as a metric filter, subscription filter or function setting needed the log group before it existed, often because the name was typed as plain text instead of referenced. Declare an AWS::Logs::LogGroup and use !Ref, or add DependsOn, so it is created first.

Are CloudWatch log group names case-sensitive?

Yes. /aws/lambda/Booking and /aws/lambda/booking are different log groups, and even the --log-group-name-pattern search is case-sensitive. Copy the exact name from describe-log-groups or the console instead of typing it from memory.

Why does aws logs tail say the log group does not exist when I can see it in the console?

Your CLI is using a different Region or account from the console. Run aws configure get region and aws sts get-caller-identity, compare them with the console's top bar, then add --region and --profile to the tail command.

What does "the specified log group does not exist in this account" mean?

The account you are signed in to has no log group with that name in that Region. Check aws sts get-caller-identity for the account number. If the logs live in another account, switch profiles, or in a cross-account monitoring setup, use the log group's ARN.

Where are Lambda@Edge logs?

In a log group named /aws/lambda/us-east-1.FunctionName, created in each Region where the function handled requests, not only in us-east-1. The CloudFront console shows the function's metrics per Region, with a way to open each Region's logs.

Why does Git Bash add C:/Program Files/Git to my log group name?

Git Bash converts arguments that start with a forward slash into Windows paths, and its root is C:/Program Files/Git. Prefix the command with MSYS_NO_PATHCONV=1, or run it from PowerShell or Command Prompt, to pass /aws/lambda/... unchanged.

How do I view CloudWatch logs from the command line?

Use aws logs tail with the log group name and its Region, for example aws logs tail /aws/lambda/booking-api --region us-east-2 --since 1h. Add --follow to keep watching, or --filter-pattern ERROR to show only matching lines. It needs AWS CLI version 2.

What is the difference between a log group and a log stream?

A log group is the container for one application's logs, such as /aws/lambda/booking-api, with its own retention and permissions. Log streams are the sequences of events inside it, typically one per running copy of the code. The two errors, log group and log stream, point to different fixes.

What does "the specified log stream does not exist" mean?

The log group was found, but no stream has that exact name. List real names with aws logs describe-log-streams, watch for $LATEST being swallowed inside double quotes, or use aws logs tail, which reads every stream in the group without a stream name.

What is the default retention of a CloudWatch log group?

By default, log events in a new log group never expire. Set a retention period with aws logs put-retention-policy, or in CloudFormation, CDK or Terraform, to control cost. Retention deletes old events, never the log group itself.

Can I stop someone deleting a CloudWatch log group?

Yes. Deletion protection blocks every deletion of a log group until it is switched off again. Turn it on with aws logs put-log-group-deletion-protection, or when creating the group. New log groups start without it.

Which IAM permissions does writing to CloudWatch Logs need?

logs:CreateLogStream and logs:PutLogEvents to write into an existing log group, plus logs:CreateLogGroup if the service must create the group. AWSLambdaBasicExecutionRole and CloudWatchAgentServerPolicy include all three.

Why can't I find my API Gateway execution logs?

Execution logs go to API-Gateway-Execution-Logs_ followed by the API ID and stage name, and only after logging is switched on for the stage with a CloudWatch role ARN set in that Region's API Gateway account settings. Each Region needs its own setting.

Jake still has his one AWS command, but now it has two more words on the end: --region us-east-2. Ethan saved it in a little script on the shop laptop called booking-logs, so Jake never has to remember it. The customer with the letter in her phone number got her booking, plus a discount for the trouble. And when Jake sees "does not exist" anywhere now, his first thought is no longer that something was deleted. It is the one Ethan gave him: check which branch you are standing in.

📌 If you keep one line from this page

Find the log group before you create one: exact name, right Region, right account.

Lambda creates its group on the first run; ECS only when awslogs-create-group is "true" and the role allows it.

Revision note. Written October 12, 2026, for everyone whose logs vanished and turned out to be one Region away. As the old saying goes, the thing you lost is usually in the last place you look, so look in the right Region first.

Related